자바 테스트 프레임 워 크 Mockito 의 간단명료 한 튜 토리 얼
Mock 테스트 는 테스트 과정 에서 쉽게 구성 되 지 않 거나(예 를 들 어 HttpServletRequest 는 Servlet 용기 에서 구성 되 어야 합 니 다)복잡 한 대상(예 를 들 어 JDBC 의 ResultSet 대상)을 쉽게 얻 지 못 하거나 가상 대상(Mock 대상)으로 테스트 할 수 있 는 테스트 방법 을 만 드 는 것 입 니 다.
Mock 의 가장 큰 기능 은 유닛 테스트 의 결합 을 분해 하 는 것 입 니 다.코드 가 다른 클래스 나 인터페이스 에 의존 하면 이러한 의존 도 를 모 의 하고 호출 된 의존 도 를 검증 할 수 있 습 니 다.
예 를 들 어 코드 에 이러한 의존 이 있 습 니 다.
A 종 류 를 테스트 해 야 할 때 Mock 이 없 으 면 모든 의존 트 리 를 구축 해 야 합 니 다.Mock 을 사용 하면 구 조 를 분해 할 수 있 습 니 다.아래 와 같이:
Mock 개체 사용 범주
실제 대상 은 불확실 한 행 위 를 하고 예측 할 수 없 는 효과 가 발생 한다(예 를 들 어 주식 시세,일기예보).
실제 대상 이 만 들 기 어 려 운실제 대상 의 일부 행 위 는 촉발 되 기 어렵다4.567917.실제 대상 이 실제로 존재 하지 않 는(다른 개발 팀 이나 새로운 하드웨어 와 접촉)등Mock 대상 테스트 를 사용 하 는 관건 적 인 절차
4.567917.하나의 인 터 페 이 스 를 사용 하여 이 대상 을 묘사 합 니 다.4.567918.
제품 코드 에서 이 인 터 페 이 스 를 실현 합 니 다테스트 코드 에서 이 인 터 페 이 스 를 실현 합 니 다4.567917.피 테스트 코드 에서 인터페이스 로 만 대상 을 인용 하기 때문에 이 인용 대상 이 실제 대상 인지 Mock 대상 인지 모른다Mock 과 Stub 의 차이
Mock 은 Stub 가 아니 라 차이 가 있 습 니 다.
현재 자바 진영 의 주요 Mock 테스트 도 구 는 Mockito,JMock,Easy Mock 등 이 있다.
이런 틀 에 대한 비 교 는 본문의 중점 이 아니다.본 고 는 Mockito 의 사용 에 중심 을 두 고 소개 한다.
Mockito 의 특성
Mockito 는 맛 있 는 자바 유닛 테스트 Mock 프레임 워 크,오픈 소스 입 니 다.
대부분의 자바 Mock 라 이브 러 리,예 를 들 어 Easy Mock 이나 JMock 은 expect-run-verify(기대-실행-검증)방식 이 고 Mockito 는 더욱 간단 하고 직관 적 인 방법 을 사용한다.실행 후의 상호작용 에서 질문 을 한다.Mockito 를 사용 하면 원 하 는 것 을 검증 할 수 있 습 니 다.한편,expect-run-verify 방식 을 사용 하 는 라 이브 러 리 는 항상 무관 한 상호작용 을 볼 수 밖 에 없다.
비 expect-run-verify 방식 은 Mockito 가 비 싼 초기 작 동 을 준비 할 필요 가 없다 는 것 을 의미한다.이들 의 목 표 는 투명 하 게 개발 자 들 이 선 정 된 행 위 를 테스트 하 는 데 전념 하도록 하 는 것 이다.
Mockito 가 가지 고 있 는 매우 적은 API 는 모두 Mockito 를 사용 하기 시 작 했 고 시간 비용 이 거의 없 었 다.mock 을 만 드 는 방법 밖 에 없 으 니까.실행 전 stub 를 기억 하고 대화 에서 검증 합 니 다.너 는 곧 이런 TDD 자바 코드 가 얼마나 자 연 스 러 운 지 알 게 될 것 이다.
Easy Mock 과 같은 문법 으로 왔 기 때문에 안심 하고 재 구성 할 수 있 습 니 다.Mockito 는'expectation(기대)'이라는 개념 이 필요 하지 않다.stub 와 검증 만 있 습 니 다.
Mockito 는 Gerard Messaros 의 이른바 Test Spy 를 실현 했다.
기타 특징:
인터페이스 뿐만 아니 라 mock 의 구체 적 인 종 류 를 만 들 수 있 습 니 다.
주해 문법 사탕[email protected].깨끗 한 검증 오 류 는-스 택 추적 을 클릭 하여 테스트 에서 의 실패 검증 을 보 는 것 입 니 다.이상 한 원인 을 클릭 하여 코드 의 실제 상호작용 을 탐색 합 니 다.스 택 추적 은 항상 깨끗 하 다4.567917.유연 하고 질서 있 는 검증 을 허용 합 니 다(예 를 들 어 모든 단독 적 인 상호작용 이 아 닌 임의의 질서 있 는 verify)
mockito 의존 성명
Gradle 사용 자 는 다음 을 사용 할 수 있 습 니 다.
repositories { jcenter() }
dependencies { testCompile "org.mockito:mockito-core:1.+" }
예시1.행위 검증
//Let's import Mockito statically so that the code looks clearer
import static org.mockito.Mockito.*;
//mock creation
List mockedList = mock(List.class);
//using mock object
mockedList.add("one");
mockedList.clear();
//verification
verify(mockedList).add("one");
verify(mockedList).clear();
mock 을 만 들 면 모든 상호작용 을 기억 합 니 다.너 는 네가 흥 미 를 느끼 는 어떤 상호작용 도 선택 하여 검증 할 수 있다2.stubbing
//You can mock concrete classes, not just interfaces
LinkedList mockedList = mock(LinkedList.class);
//stubbing
when(mockedList.get(0)).thenReturn("first");
when(mockedList.get(1)).thenThrow(new RuntimeException());
//following prints "first"
System.out.println(mockedList.get(0));
//following throws runtime exception
System.out.println(mockedList.get(1));
//following prints "null" because get(999) was not stubbed
System.out.println(mockedList.get(999));
//Although it is possible to verify a stubbed invocation, usually it's just redundant
//If your code cares what get(0) returns, then something else breaks (often even before verify() gets executed).
//If your code doesn't care what get(0) returns, then it should not be stubbed. Not convinced? See here.
verify(mockedList).get(0);
4.567917.기본 적 인 상황 에서 모든 방법 은 값 을 되 돌려 줍 니 다.하나의 mock 은 null,원시/기본 유형의 포장 값 또는 적당 한 빈 집합 을 되 돌려 줍 니 다.예 를 들 어 int/Integer 는 0 이 고 boolean/Boolean 은 false 입 니 다4.567917.Stubbing 은 덮어 쓸 수 있 습 니 다4.567917.stub 가 되면 이 방법 은 몇 번 호출 되 든 stub 의 값 을 되 돌려 줍 니 다4.567917.마지막 stubbing 은 매우 중요 합 니 다.-같은 매개 변 수 를 사용 할 때 stub 는 같은 방법 을 여러 번 사용 합 니 다.다시 말 하면 stubbing 의 순 서 는 중요 하지만 유일 하 게 의미 가 있 는 것 은 매우 적다.예 를 들 어 stubbing 이 똑 같은 방법 으로 호출 되 거나 매개 변수 매 칭 기 에서 사용 되 는 등 이다3.매개 변수 정합 기Mockito 인증 매개 변수 값 은 자바 방식 을 사용 합 니 다:equals()방법 을 사용 합 니 다.때때로 추가 적 인 유연성 이 필요 할 때 매개 변수 매 칭 기 를 사용 할 수 있다.
//stubbing using built-in anyInt() argument matcher
when(mockedList.get(anyInt())).thenReturn("element");
//stubbing using custom matcher (let's say isValid() returns your own matcher implementation):
when(mockedList.contains(argThat(isValid()))).thenReturn("element");
//following prints "element"
System.out.println(mockedList.get(999));
//you can also verify using an argument matcher
verify(mockedList).get(anyInt());
매개 변수 매 칭 기 는 유연 한 검증 이나 stubbing 을 허용 합 니 다.내 장 된 매 칭 기와 사용자 정의 매개 변수 매 칭 기/hamcrest 매 칭 기의 예 를 보 려 면 여 기 를 누 르 십시오.매개 변수의 일치 정 보 를 사용자 정의 합 니 다.자바 doc 의 Argument Matcher 클래스 를 보십시오.
매개 변수 매 칭 을 사용 하고 있다 면 모든 매개 변 수 는 매 칭 기 에서 제공 합 니 다.
다음 예제 에 서 는 검증 을 보 여 줍 니 다.그러나 stubbing 에 도 적 용 됩 니 다.
verify(mock).someMethod(anyInt(), anyString(), eq("third argument"));
//above is correct - eq() is also an argument matcher
verify(mock).someMethod(anyInt(), anyString(), "third argument");
//above is incorrect - exception will be thrown because third argument is given without an argument matcher.
4.추가 호출 숫자/at least x/never 호출
//using mock
mockedList.add("once");
mockedList.add("twice");
mockedList.add("twice");
mockedList.add("three times");
mockedList.add("three times");
mockedList.add("three times");
//following two verifications work exactly the same - times(1) is used by default
verify(mockedList).add("once");
verify(mockedList, times(1)).add("once");
//exact number of invocations verification
verify(mockedList, times(2)).add("twice");
verify(mockedList, times(3)).add("three times");
//verification using never(). never() is an alias to times(0)
verify(mockedList, never()).add("never happened");
//verification using atLeast()/atMost()
verify(mockedList, atLeastOnce()).add("three times");
verify(mockedList, atLeast(2)).add("five times");
verify(mockedList, atMost(5)).add("three times");
times(1)는 기본 값 이기 때문에 사용 하 는 times(1)는 생략 할 수 있 습 니 다.5.Stubbing void 방법 처리 이상
doThrow(new RuntimeException()).when(mockedList).clear();
//following throws RuntimeException:
mockedList.clear();
6.질서 있 는 검증
// A. Single mock whose methods must be invoked in a particular order
List singleMock = mock(List.class);
//using a single mock
singleMock.add("was added first");
singleMock.add("was added second");
//create an inOrder verifier for a single mock
InOrder inOrder = inOrder(singleMock);
//following will make sure that add is first called with "was added first, then with "was added second"
inOrder.verify(singleMock).add("was added first");
inOrder.verify(singleMock).add("was added second");
// B. Multiple mocks that must be used in a particular order
List firstMock = mock(List.class);
List secondMock = mock(List.class);
//using mocks
firstMock.add("was called first");
secondMock.add("was called second");
//create inOrder object passing any mocks that need to be verified in order
InOrder inOrder = inOrder(firstMock, secondMock);
//following will make sure that firstMock was called before secondMock
inOrder.verify(firstMock).add("was called first");
inOrder.verify(secondMock).add("was called second");
// Oh, and A + B can be mixed together at will
질서 있 는 검증 은 유연성 을 위 한 것 입 니 다.-모든 상호작용 을 하나씩 검증 할 필요 가 없습니다.또한,InOrder 대상 을 만들어 질서 있 는 검증 과 관련 된 mock 만 전달 할 수 있 습 니 다.
7.mock 에서 상호작용 이 일어나 지 않도록 확보
//using mocks - only mockOne is interacted
mockOne.add("one");
//ordinary verification
verify(mockOne).add("one");
//verify that method was never called on a mock
verify(mockOne, never()).add("two");
//verify that other mocks were not interacted
verifyZeroInteractions(mockTwo, mockThree);
8.불필요 한 호출 찾기
//using mocks
mockedList.add("one");
mockedList.add("two");
verify(mockedList).add("one");
//following verification will fail
verifyNoMoreInteractions(mockedList);
메모:verify NoMore Interactions()는 모든 테스트 방법 에서 사용 하 는 것 을 권장 하지 않 습 니 다.verify NoMore Interactions()는 상호작용 테스트 도구 패키지 에서 편리 한 단언 입 니 다.그것 과 관련 이 있 을 때 만 그것 을 사용한다.그것 을 남용 하여 유지 하기 어렵다.9.표준 생 성 mock 방식-@Mock 주석 사용
public class ArticleManagerTest {
@Mock private ArticleCalculator calculator;
@Mock private ArticleDatabase database;
@Mock private UserProvider userProvider;
private ArticleManager manager;
기본 클래스 나 테스트 runner 에서 다음 과 같이 사용 합 니 다.MockitoAnnotations.initMocks(testClass);
내장 runner:MockitoJUnitRunner 또는 rule:MockitoRule 사용 가능10.Stubbing 연속 호출(교체 기 식 stubbing)
when(mock.someMethod("some arg"))
.thenThrow(new RuntimeException())
.thenReturn("foo");
//First call: throws runtime exception:
mock.someMethod("some arg");
//Second call: prints "foo"
System.out.println(mock.someMethod("some arg"));
//Any consecutive call: prints "foo" as well (last stubbing wins).
System.out.println(mock.someMethod("some arg"));
다음은 간소화 버 전 입 니 다.
when(mock.someMethod("some arg"))
.thenReturn("one", "two", "three");
11.리 턴 스 터 빙범용 Answer 인 터 페 이 스 를 사용 할 수 있 습 니 다.
그러나 이 는 최초의 모 키 토 에 포함 되 지 않 은 또 다른 논란 의 기능 이다.저 희 는 thenReturn()이나 thenThrow()로 stubbing 을 사용 하 는 것 을 권장 합 니 다.이것 은 테스트/테스트 구동 에서 간결 하고 간단 한 코드 를 사용 하면 충분 합 니 다.그러나 만약 에 stub 에서 범 형 Answer 인터페이스 까지 필요 한 것 이 있다 면 이것 은 하나의 예 입 니 다.
when(mock.someMethod(anyString())).thenAnswer(new Answer() {
Object answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
Object mock = invocation.getMock();
return "called with arguments: " + args;
}
});
//the following prints "called with arguments: foo"
System.out.println(mock.someMethod("foo"));
12.doReturn()|doThrow()|doAnswer()|doNothing()|doCallRealMethod()가족 방법Stubbing void 방법,서로 다른 when(Object)이 필요 합 니 다.컴 파일 러 는 괄호 안에 잘못된 방법 을 좋아 하지 않 기 때 문 입 니 다.
Stubbing void 방법 에서 doThrow(Throwable...)는 stubVoid(Object)를 대체 합 니 다.가 독성 을 높이 고 doAnswer()와 일치 성 을 유지 하기 때문이다.
doThrow()를 stub void 방법 으로 사용 하려 면:
doThrow(new RuntimeException()).when(mockedList).clear();
//following throws RuntimeException:
mockedList.clear();
when()을 호출 할 때 oThrow(),doAnswer(),doNothing(),doReturn(),doCallRealMethod()를 사용 할 수 있 습 니 다.stub void 방법
stub 방법 은 스파이 대상(아래 참조)4.567917.한 번 이 아 닌 stub 와 같은 방법 으로 테스트 중반 에 mock 의 행 위 를 바 꿀 수 있 습 니 다.
그러나 when()대신 이 방법 을 사용 하 는 경향 이 있 습 니 다.모든 stubbing 에서 호출 됩 니 다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.