본문 바로가기
공부하는 하스씨/안드로이드

Mockito 매뉴얼 한글화 (2010년)

by 박하스. 2016. 8. 1.
728x90
반응형

원글출처 : 

http://sapzildj.tistory.com/4 

 

학습을 위해 긁어옴.

 
 

Mockito 매뉴얼 한글화

Java 2010.07.02 13:21
크리에이티브 커먼즈 라이선스
Creative Commons License

Mockito 매뉴얼 한글화

Mockito 매뉴얼 한글화

원본 URL = http://mockito.googlecode.com/svn/tags/latest/javadoc/org/mockito/Mockito.html

last update = 2010/05/11


사용 매뉴얼을 한글로 번역해봤습니다. 추후 시간이 나면 java doc 내용도 한글화를 해보겠습니다.
오타나 잘못된 내용은 말씀해주세요~(rhanwith@naver.com)
허접한 번역이지만 상업적인 용도로 사용을 금지합니다.

 

한국 개발자들의 Mockito 사용 레퍼런스

 http://kwon37xi.egloos.com/4165915 - 왜 Mockito가 좋은가?왜 Mockito가 좋은가?

[Mockito] void 메서드 stubbing 새로운 방법
http://whiteship.me/1828 - Mockito - 아규먼트 Matcher
Mockito를 이용한 MockTest

 

 

 

 

org.mockito
Class Mockito

java.lang.Object org.mockito.Matchers org.mockito.Mockito
Direct Known Subclasses:
BDDMockito

public class Mockito
extends Matchers

 

Mockito 라이브러리는 mock들을 생성하고 검증하고 스터빙(stubbing)을 가능하게 한다.

This javadoc content is also available on the http://mockito.org web page. All documentation is kept in javadocs because it guarantees consistency between what's on the web and what's in the source code. Also, it makes possible to access documentation straight from the IDE even if you work offline.

Contents

1. 어떤 행위(behaviour)를 검증해보자!
2. 스터빙(stubbing)은 어떨까?
3. 함수 인자 적합자(matchers)
4. 수행(invocations)한 정확한 횟수 검증 / 적어도 한번 / 한번도 안한
5. 예외(exceptions)와 함께 void 메소드들을 스터빙(stubbing) 해보기
6. 순서대로 검증 해보기
7. mock과의 상호작용이 한번도 없었는지 확인
8. 불필요한 수행(invocation) 찾기
9. mock 생성 간단 버전 - @Mock 어노테이션
10. 연속 메소드 호출에 대한 스터빙(stubbing) - (iterator-style stubbing)
11. 콜백을 이용한 스터빙(stubbing)
12. (대부분) void 메소드들에 대한 스터빙(stuubing)을 위한 doThrow()|doAnswer()|doNothing()|doReturn() 메소드류
13. 실제 객체들에 대한 감시(spying)
14. 스텁(stub) 되지 않은 수행(invocation) 시 기본 리턴값 변경(1.7 버전 부터)
15. 더 나은 단언(assertion)을 위한 함수 인자 캡쳐하기(1.8.0 버전 부터)
16. 진짜로 부분적인 mock(1.8.0 버전 부터)
17. mock 리셋(1.8.0 버전 부터)
18. 트러블 슈팅(Troubleshooting) & 프레임웍 사용 검증하기(1.8.0 버전 부터)
19. 행위 주도 개발(BDD, behavior driven development)을 위한 별칭(Aliases) (1.8.0 버전 부터)
20. 직렬화 가능한(Serializable) mock(1.8.1 버전 부터)
21. 새로운 어노테이션 : @Captor, @Spy, @InjectMocks (1.8.3 버전 부터)
22. (**신규**) 타임 아웃에 대한 검증(1.8.5 버전 부터)

아래 예제에서 List를 mock한 이유는 모든 사람이 그 인터페이스를 알고 있기 때문이다.(add(), get(), clear() 등).
당신 아마도 List클래스를 진짜로 제대로 mock 해보진 못했을 것이다.

1. 어떤 행위(behaviour)를 검증해보자!

  1. // Mockito를 static import로 처리하면 코드가 더 보기 좋다. 
      import static org.mockito.Mockito.*;
    // mock 생성 
      List mockedList = mock(List.class);
    // mock 객체을 이용
      mockedList.add("one"); 
      mockedList.clear(); 
    
    // 검증 
      verify(mockedList).add("one"); 
      verify(mockedList).clear();

한번 생성된 mock은 모든 상호 작용(interactions)을 기억하므로, 당신은 선택적으로 어떤 관심 있는 상호 작용이든 검증할 수 있다.

2. 스터빙(stubbing)은 어떨까?

  1. // 당신은 인터페이스 뿐만 아니라 구체화된(concrete) 클래스들을 mock이 가능하다. 
      LinkedList mockedList = mock(LinkedList.class);
    // 스터빙(stubbing) 
      when(mockedList.get(0)).thenReturn("first"); 
      when(mockedList.get(1)).thenThrow(new RuntimeException());
    // 아래는 "first"를 출력한다.
      System.out.println(mockedList.get(0));
    // 아래는 runtime exception이 발생한다.
      System.out.println(mockedList.get(1));
    // 아래는 "null"을 출력한다. get(999)은 스텁(stub)되지 않았기 때문이다. 
      System.out.println(mockedList.get(999));
    // 스텁된 수행(stubbed invocation)에 대한 검증이 가능이 가능하긴 하지만 보통 그것은 불필요하다. 
      // 당신의 코드에서 get(0)이 뭘 리턴하는 지 관심이 있다면 처리하고 아니라면 넘어가라(보통 verify()가 실행되기도 전에 그렇게 함). 
      // 당신의 코드에서 get(0)이 뭘 리턴하든 관심 없다면 스텁(stub)하지 않는 것이 맞다. 납득되지 않는다면 여기를 보라(here).
      verify(mockedList).get(0);
  • 기본적으로, 값을 리턴하는 모든 메소드들에 대해 mock은 null, 빈 콜렉션(collectionn), 적절한 primitive/primitive wrapper value를 리턴한다.(예: 0, false, ... for int/Integer, boolean/Boolean, ...).
  • 스터빙(Stubbing)은 오버라이드 될 수 있다 : 예를 들어 공통적인 스터빙은 고정 기본 작업(fixture setup)이 가능하고, 테스트 메소드들도 오버라이드가 가능하다. 유념할 부분은 오버라이드된 스터빙(stubbing)은 과도한 스터빙에 대한 코드 냄새(code smell)가 잠재해있다는 점이다.
  • 한번 스텁된(stubbed) 메소드는 몇번 호출되었든지 상관 없이 항상 스텁된 값을 리턴한다.
  • 바로 전 스터빙(stubbinng)은 더욱 중요하다 - 당신이 같은 함수 인자들로 여러번 같은 메소드를 스터빙할 때

3. 함수 인자 적합자(matchers)

Mockito는 기본적인 자바 스타일로(equals() 메소드를 사용) 함수 인자 값들을 검증한다. 종종, 추가적인 유연함이 필요한 경우 당신은 함수 인자 적합자(argument matchers)를 사용할 수 있다.

  1. // 기본적으로 내장된(built-in) anyInt() 함수 인자 적합자를 이용한 스터빙(stubbing) 
      when(mockedList.get(anyInt())).thenReturn("element");
    // hamcrest를 이용한 스터빙(isValid()는 당신의 hamcrest matcher를 리턴한다고 가정): 
      when(mockedList.contains(argThat(isValid()))).thenReturn("element");
    // 아래는 "element" 출력
      System.out.println(mockedList.get(999));
    // 함수 인자 적합자를 사용해서 검증도 가능하다. 
      verify(mockedList).get(anyInt());

함수 인자 적합자는 유연한 검증이나 스터빙이 가능하게 한다. 여기(Click here to see)에는 더 많은 기본적으로 내장된 적합자들과 별도 함수 인자 적합자(custom argument matchers), / 햄크레스트 적합자(hamcrest matchers).

별도 함수 인자 적합자에 대한 정보를 얻기 위한 유일한 곳은 ArgumentMatcher 클래스의 자바 독이니 확인을 해보도록 한다.

복잡한 함수 인자 적합(matching)을 사용할 때에는 그에 대한 책임을 가져야 한다. 몇몇 경우에 anyX() 적합자들과 함께 사용되는 equals()를 이용한 자연스러운 적합 스타일은 깨끗하고 간결한 테스트들로 만들어 주는 경향이 있다. 또, 어떤 경우에는 코드를 리팩토링하는 것 보다 equals() 적합이나 테스팅을 돕기 위한 equals() 메소드 구현(implement) 등이 더 나은 경우가 있다.

section 15ArgumentCaptor 클래스에 대한 자바독을 참고하길 바란다. ArgumentCaptor 는 더 나은 단언(assertions)를 위해 함수 인자를 수집(capturinng)하는 특성을 가진 함수 인자 적합자의 구현체이다.

함수 인자 적합자에서 주의할 점:

함수 인자 적합자를 사용 하는 경우, 모든 함수 인자들은 적합자로서 주어져야 한다.

예: (아래 예제에서는 검증에 대해서만 다루지만, 스터빙 역시 적용된다):

  1. verify(mock).someMethod(anyInt(), anyString(), eq("third argument")); 
      // 위 코드는 옳다 - eq() 역시 함수 인자 적합자이다.
    verify(mock).someMethod(anyInt(), anyString(), "third argument"); 
      //위 코드는 틀리다 - 3번째 인자가 함수 인자 적합자 없이 주어져서 예외(exception)가 던져진다.

4. 수행(invocations)한 정확한 횟수 검증 / 적어도 한번 / 한번도 안한

  1. // mock 사용
      mockedList.add("once"); 
      mockedList.add("twice");
      mockedList.add("twice"); 
    
    mockedList.add("three times"); 
      mockedList.add("three times"); 
      mockedList.add("three times");
    // 아래 2 검증들은 완전히 동일하게 작동한다 - times(1)은 기본값으로 사용됨 
      verify(mockedList).add("once"); 
      verify(mockedList, times(1)).add("once");
    // 정확한 수행(invocations) 횟수 검증 
      verify(mockedList, times(2)).add("twice"); 
      verify(mockedList, times(3)).add("three times");
    // never() 를 이용한 검증은 times(0)의 별칭(alias)이다.
      verify(mockedList, never()).add("never happened");
    // 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. 예외(exceptions)와 함께 void 메소드들을 스터빙(stubbing) 해보기

  1. doThrow(new RuntimeException()).when(mockedList).clear();
    // 아래는 RuntimeException을 던진다.
      mockedList.clear();

doThrow|doAnswer 류의 메소드들에 대해 더 알고 싶으면 paragraph 12를 참고하면 된다.

처음에는, stubVoid(Object)가 void 메소드들을 스터빙하기 위해 사용됐었지만, 현재 stubVoid()는 deprecated 됐고, doThrow(Throwable)를 권장한다. 그 이유는 doAnswer(Answer) 메소드류가 가독성과 일관성 면에서 더 낫기 때문이다.

6. 순서대로 검증 해보기

  1. List firstMock = mock(List.class); 
      List secondMock = mock(List.class);
    // mock들을 이용 
      firstMock.add("was called first"); 
      secondMock.add("was called second");
    // 순서에 대한 검증이 필요한 몇몇 mock들을 넘겨서 inOrder 객체를 생성한다. 
      InOrder inOrder = inOrder(firstMock, secondMock);
    // 아래는 secondMock 전에 firstMock이 호출됐다는 것을 검증한다. 
      inOrder.verify(firstMock).add("was called first"); 
      inOrder.verify(secondMock).add("was called second");

순서가 있는 검증은 유연하다 - 당신이 관심 있는 순서가 있는 테스팅 하나 하나의 모든 상호 작용(interactions)을 검증할 필요는 없다.

그리고, 당신은 순서가 필요한 적절한 mock들을 넘겨서 InOrder 객체를 생성할 수 있다.

7. mock과의 상호작용이 한번도 없었는지 확인

  1. // mock 사용 - 오직 mockOne만 상호 작용 한다. 
      mockOne.add("one");
    // 일반적인 검증 
      verify(mockOne).add("one");
    // mock에 아래 메소드를 한번도 호출 안했는지 검증 
      verify(mockOne, never()).add("two");
    // 다른 mock들은 상호 작용이 없었는지 검증 
      verifyZeroInteractions(mockTwo, mockThree);

8. 불필요한 수행(invocation) 찾기

  1. // mock 사용 
      mockedList.add("one"); 
      mockedList.add("two");
    verify(mockedList).add("one");
    // 아래 검증은 실패 
      verifyNoMoreInteractions(mockedList);

경고 : 기대-실행-검증(expect-run-verify) mocking 스타일의 많은 고전 방식 사용자들은 verifyNoMoreInteractions() 매우 자주 사용하는 경향이 있다. 모든 테스트 메소드에서 조차. 모든 테스트 메소드에서의 verifyNoMoreInteractions() 사용은 권장하지 않는다. verifyNoMoreInteractions()는 테스팅 도구(testing tool kit) 상호 작용으로 부터의 유용한 단언(assertion)이다. 적절한 곳에서만 사용해라. 이 메소드의 남용은 과도한 명시화(overspecified)를 초래한다. 유지 보수하는 테스트들에서는 덜 사용하는 것이 좋겠다. 여기(here)에는 더 많은 읽을 꺼리가 있다.

never() 역시 확인해 볼 것 - 좀더 명쾌하고 의도하는 바를 잘 전달할 수 있다.

9. mock 생성 간단 버전 - @Mock 어노테이션

  • 반복적인 mock 생성 코드를 최소화한다.
  • 테스트 클래스의 가독성을 향상시킨다.
  • mock을 구별하기 위해 사용한 필드명 때문에 검증 에러 를 읽기가 더 쉽다.
  1. public class ArticleManagerTest { 
      @Mock private ArticleCalculator calculator; 
      @Mock private ArticleDatabase database; 
      @Mock private UserProvider userProvider;
  2. private ArticleManager manager;

중요! 이 어노테이션은 기본 클래스(base class)상에서나 테스트 러너에서 다음 코드를 필요로 한다:

MockitoAnnotations.initMocks(testClass);

기본 내장된 러너를 사용할 수 있다: MockitoJUnitRunner.

좀더 많은 것이 여기(MockitoAnnotations)

10. 연속 메소드 호출에 대한 스터빙(stubbing) - (iterator-style stubbing)

종종 우리는 같은 메소드 호출에 대해 다른 리턴 값/예외를 갖는 스텁이 필요하다. 일반적인 경우 mocking iterators로 사용될 수 있다. Mockito 원래 버전은 단순한 mockinng을 권장하기 위해 기능을 포함하지 않았다. 예를 들면, iterators 대신에 Iterable 이나 콜렉션들(collections)을 간략화시켜서 사용할 수 있다. 이것들은 스터빙의 자연적인 방법들을 제공한다.(예: 실제 콜렉션들 사용). 드문 시나리오로는 스터빙의 연속적인 호출들에는 유용할 수 있다. 이렇게:

  1. when(mock.someMethod("some arg")) 
      .thenThrow(new RuntimeException()) 
      .thenReturn("foo");
    // 첫번째 호출: runtime exception을 던진다: 
      mock.someMethod("some arg");
    // 두번째 호출: "foo" 출력
      System.out.println(mock.someMethod("some arg"));
    // 몇 번째 연속적인 호출: "foo" 출력(마지막 스터빙이 이김). 
      System.out.println(mock.someMethod("some arg"));
  2. // 대안으로, 연속적인 스터빙에 대해 이런 간략화 버전이 있다:
  3. when(mock.someMethod("some arg")) .thenReturn("one", "two", "three");

11. 콜백을 이용한 스터빙(stubbing)

일반화된(generic) Answer 인터페이스로 스터빙하는 것이 가능하다.

그러나 아직 논란의 여지가 있는 특징이라 기본적으로 Mockito에 포함하진 않았다. 우리는 오직 thenReturn()이나 thenThrow()과 함께 단순한 스터빙을 할 것을 권장한다. 이것들만으로도 테스트/테스트 주도의 간결하고 깨끗한 코드가 충분히 가능하기 때문이다.

  1. when(mock.someMethod(anyString())).thenAnswer(new Answer() { 
      Object answer(InvocationOnMock invocation) { 
      Object[] args = invocation.getArguments(); 
      Object mock = invocation.getMock(); 
      return "called with arguments: " + args; 
      } 
      });
    // 아래는 "called with arguments: foo"를 출력한다.
      System.out.println(mock.someMethod("foo"));

12. (대부분) void 메소드들에 대한 스터빙(stuubing)을 위한 doThrow()|doAnswer()|doNothing()|doReturn() 메소드 시리즈들

void 메소드들을 스터빙할 때에는 when(Object)과는 다른 접근을 요구한다. 컴파일러는 괄호 안에 void 메소드를 좋아하지 않기 때문이다....

doThrow(Throwable)는 void 메소드를 스터빙할 때 쓰던 stubVoid(Object)를 대신한다. 주된 이유는 doAnswer() 류 메소드가 가독성과 일관성면에서 더 낫기 때문이다.

에외와 함께 void 메소드를 스텁(stub)하기를 원한다면 doThrow()를 사용하라. :

  1. doThrow(new RuntimeException()).when(mockedList).clear();
  2. // 아래는 RuntimeException을 던진다 
      mockedList.clear();

다른 메소드들에 대해서도 볼 것:

doThrow(Throwable)

doAnswer(Answer)

doNothing()

doReturn(Object)

13. 실제 객체들에 대한 감시(spying)

당신은 실제 객체들의 스파이들을 생성할 수 있다. 스파이를 사용하면 실제 메소드들이 호출된다.(메소드가 스텁되지 않는 한).

실제 스파이들은 조심스럽게 사용되어야 한다. 예를 들면 레거시 코드(legacy code)를 다루는 경우가 해당한다.

실제 객체들을 감시하는 것은 부분적인 mockinng 컨셉과 관련이 있다. 1.8 릴리즈 전에는 Mockito 스파이들은 실제 부분적인 mock들이 아니었다. 그 이유는 우리가 부분적인 mock은 코드 악취(code smell)이라 생각했기 때문이다. 어떤 면에서 우리는 부분적인 mock들에 대한 적절한 사용 사례들을 찾아냈다.(써드 파티 라이브러리(3rd party interfaces), 레거시 코드의 리팩토링 중인 상태, 전체 아티클은 여기에 here)

  1. List list = new LinkedList(); 
      List spy = spy(list);
    // 필요하다면, 몇몇 메소드들을 스텁할 수 있다.: 
      when(spy.size()).thenReturn(100);
    // 스파이를 사용해서 실제 메소드들을 호출 
      spy.add("one"); 
      spy.add("two");
    // "one" 출력 - list의 첫번째 엘리먼트(element) 
      System.out.println(spy.get(0));
    // size() 메소드는 스텁됐다. - 100 이 출력됨. 
      System.out.println(spy.size());
    // 필요하다면 검증도 가능하다. 
      verify(spy).add("one"); verify(spy).add("two");

실제 객체들을 감시할 때 중요한 점!

1. 어떤 경우 스터빙하는 스파이들에 대해 when(Object)가 불가능하다 . 아래는 그 예제이다:

  1. List list = new LinkedList(); 
      List spy = spy(list);
    // 불가능: 실제 메소드가 호출되어 spy.get(0)은 IndexOutOfBoundsException을 던짐(list가 아직 빈 상태) 
      when(spy.get(0)).thenReturn("foo");
    // 당신은 스터빙을 위해 doReturn()을 사용해야 한다.
      doReturn("foo").when(spy).get(0);

2. 마지막 메소드들을 잘 살펴봐라. Mockito는 마지막 메소드들을 mock하지 않으므로 마지막 라인은 : 당신이 실제 객체들을 감시할 때 + 당신이 마지막 메소드를 스텁하려고 시도할 때 = 문제 발생. mock상에서 실제 메소드가 호출 되었는데, 당신이 spy() 메소드로 넘긴 실제 인스턴스는 없을 때 어떤 일이 발생할까? 일반적으로 mock 인스턴스들이 초기화된 필드들을 갖고 있지 않으므로 NullPointerException 발생한다.

14. 스텁(stub) 되지 않은 수행(invocation) 시 기본 리턴값 변경(1.7 버전 부터)

당신은 리턴 값에 대해 특정한 전략을 가진 mock을 생성할 수 있다. 이것은 완전 고급 기능으로, 일반적으로 양질의 테스트들을 만드는 경우 사용할 필요가 없다. 그런데, 레거시 시스템(legacy systems)에서 진행하는 경우 도움이 될 수 있다.

이것은 당신이 메소드 호출을 스텁하지 않을 때 사용될 때의 기본 대답(answer)이다.

  1. Foo mock = mock(Foo.class, Mockito.RETURNS_SMART_NULLS);
    Foo mockTwo = mock(Foo.class, new YourOwnAnswer());

이 내용과 관련된 재미있는 대답(Answer)의 구현체(implementation)가 있다: RETURNS_SMART_NULLS

15. 더 나은 단언(assertion)을 위한 함수 인자 캡쳐하기(1.8.0 버전 부터)

Mockito는 함수 인자 값들을 equals()를 사용해서 기본적인 자바 스타일로 검증한다. 이러한 검증 방식은 테스트들을 깨끗하고 간결하게 해서 함수 인자 적합(matching arguments)에 권장된다. 몇몇 상황에서는 진행 중인 검증 뒤에 특정 함수 인자들을 검증하는 것이 도움이 된다. 예를 들면:

  1. ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class); 
      verify(mock).doSomething(argument.capture()); 
      assertEquals("John", argument.getValue().getName());

주의: 이것은 ArgumentCaptor을 사용한 검증에서는 권장되지만, 스터빙을 하는 경우에는 그렇지 않다. 스터빙과 함께 ArgumentCaptor를 사용하는 것은 captor가 (verify 나 'then'으로 알려진)assert 블록 외부에서 생성돼서 테스트 가독성을 떨어뜨린다. 또한, 스텁된 메소드들은 호출되지 않으면 아무 인자도 수집(capture)되지 않으므로 결함 위치를 찾기 어려워 질 수 있다.

어느 정도는 ArgumentCaptor가 별도 함수 인자 적합자(custom argument matchers)와 관련이 있다.(ArgumentMatcher 클래스에 대한 자바 독을 볼 것). 두 기술 모두 mock으로 넘어온 특정 함수 인자들을 검증할 때 사용한다. 그런데, ArgumentCaptor는 아래의 경우 더 잘 맞는다:

  • 별도 함수 인자 적합자(custom argument matcher)가 재사용 되지 않을 경우
  • 단지 함수 인자값들에 대한 완벽한 검증을 위해 필요한 경우

별도 함수 인자 적합자를 활용한 ArgumentMatcher는 보통 스터빙에 대해 더 걸맞는 편이다.

16. 진짜로 부분적인 mock(1.8.0 버전 부터)

마침내, 많은 내부에서의 논의와 메일링 리스트에서의 논쟁들 후에, 부분적인 mock을 Mockito에서 지원하게 됐다. 이전에 우리는 부분적인 mock들은 코드 악취들이라고 판단했었다. 그런데, 우리는 부분적인 mock에 대한 적합한 사용 사례들을 찾았다. - 더 많은 내용은 여기(here)

1.8 릴리즈 전의 spy()는 실제 부분적인 mock들을 생성하지 않고 있었고 이는 몇몇 유저들을 혼란스럽게 했다. 감시(spying)에 대한 더 많은 내용은 여기(here)나 spy(Object) 메소드의 자바독을 참고.

  1. // 당신은 부분적인 mock을 spy() 메소드를 이용해서 생성가능하다: 
      List list = spy(new LinkedList());
    // 당신은 부분적인 mock의 기능을 선택적으로 mock에서 가능하게 할 수 있다: 
      Foo mock = mock(Foo.class); 
      // 실제 구현체(implementation)는 '안전'한 상태여야 한다. 
      // 실제 구현체가 예외를 던지거나 객체의 특정 상태에 의존성이 있다면 문제가 발생할 수 있다. 
      when(mock.someMethod()).thenCallRealMethod();

늘 그래왔듯이 당신은 부분적인 mock 경고에 대해 보고 있을 것이다: 객체 지향 프로그래밍은 복잡도를 줄이기 위해 씨름하고, 복잡한 부분을 나누고, 명확하게하고, SRPy objects로 만드는 것이다.. 어떻게 부분적인 mock이 이 패러다임에 맞겠는가? 보통 부분적인 mock은 같은 객체에서 다른 메소드로 복잡한 부분이 옮겨져야 한다는 것을 의미한다. 대부분의 경우에서, 이것은 당신이 원하는 애플리케이션의 디자인이 아닐 것이다..

그런데, 드문 경우지만 부분적인 mock들이 필요할 때가 있다. : 쉽게 고칠 수 없는 코드(써드 파티 인터페이스들, 레거시코드에서 리팩토링 진행 중일 때의 상황 등.) 그렇지만, 새로운 코드나 테스트 기반, 잘 디자인된 코드들은 그렇게 사용하지 않을 것이라 생각한다.

17. mock 리셋(1.8.0 버전 부터)

똑똑한 Mockito 유저들은 이 기능을 거의 사용할 일이 없다. 왜냐하면 그들은 이 기능이 저품질의 테스트들의 신호가 될 것이라는 것을 알고 있기 때문이다. 보통, 당신은 당신의 mock들을 리셋할 필요가 없다, 단지 각 test method마다 새 mock들을 생성하면 된다.

reset() 대신에 단순하고 작게 할 것을 고려하라. 그리고 너무 길거나 구체화된 테스트들에 집중할 필요가 있다. 첫째로 잠재적인 코드 악취는 테스트 메소드 중간의 reset()이다. 이것은 당신이 너무 많은 테스팅을 하고 있다는 뜻이다. 당신의 테스트 메소드들의 속삭임을 따르라: "우릴 작게 지켜주시고, 오직 하나의 행위에만 집중할 수 있게 해주세요". 이와 관련해서 mockito 메일링 리스트에는 많은 얘기들이 있다.

우리가 reset()을 추가한 단 하나의 이유는 컨테이너-주입(container-injected) mock들과 같이 작동이 가능하게 하기 위함이다. issue 55를 보라(here) or FAQ (here).

스스로를 깍아 내리지 마라. 테스트 메소드 중간의 reset()은 코드 악취이다.(당신은 너무 많은 테스팅을 하고 있다).

  1. List mock = mock(List.class); 
      when(mock.size()).thenReturn(10); 
      mock.add(1); 
      reset(mock); 
      // 이 지점에서 부터는 mock은 어떤 상호작용이나 스터빙에 대해 잊는다.

18. 트러블 슈팅(Troubleshooting) & 프레임웍 사용 검증하기(1.8.0 버전 부터)

무엇보다도, 어떤 문제의 경우에, Mockito FAQ: http://code.google.com/p/mockito/wiki/FAQ을 볼 것을 권장한다.

질문이 있는 경우에 당신은 mockito 메일링 리스트에 발송할 수 있다.: http://groups.google.com/group/mockito

다음으로, 당신은 Mockito가 당신이 항상 잘 사용하고 있는 것과 동시에 검증되고 있다는 것을 알아야 할 것이다. 그렇지만, 뭔가 발견했다면 validateMockitoUsage() 자바 독을 읽어 봐라.

19. 행위 주도 개발(BDD, behavior driven development)을 위한 별칭(Aliases) (1.8.0 버전 부터)

행위 주도 개발(Behavior Driven Development) 스타일로 테스트를 작성하는 경우 //given //when //then 코멘트들을 테스트 메소드들의 핵심 부분으로 사용한다. 이것은 완전히 우리가 테스트를 작성할 때 권장하는 방법이다.

BDD 대해 배우기 시작하려면 여기(http://en.wikipedia.org/wiki/Behavior_Driven_Development)를 참고하라.

문제는 //given //when //then 코멘트들과 함께 만족할 만한 수준으로 통합되지 않은 when 단어의 정석적인 역할과 함께하는 현재 스터빙 api이다. 그것은 스터빙이 테스트의 when 컴포넌트(component)가 아닌, given 컴포넌트를 따르고 있기 때문이다. 이런 이유로 BDDMockito 클래스는 당신이 BDDMockito.given(Object)메소드와 함께 스텁 메소드를 호출하면 별칭(alias)을 도입한다(introduce). 현재 이렇게 BDD 스타일 테스트의 given 컴포넌트와 멋지게 통합되었다!

아래는 테스트코드가 어떤 식으로 구성되는지 보여 준다:

  1. import static org.mockito.BDDMockito.*;
    Seller seller = mock(Seller.class); 
      Shop shop = new Shop(seller);
    public void shouldBuyBread() throws Exception { 
      //given 
      given(seller.askForBread()).willReturn(new Bread()); 
      //when 
      Goods goods = shop.buyBread(); 
      //then 
      assertThat(goods, containBread()); 
      }

20. 직렬화 가능한(Serializable) mock(1.8.1 버전 부터)

mock들은 직렬화가 가능하게(serializable) 만들수 있다. 이 기능을 이용하면 당신은 직렬화에 대한 의존성이 있는 곳에서 mock을 사용할 수 있다.

경고: 이것은 유닛 테스팅에서는 거의 사용되지 않아야 한다.

행위(behaviour)는 안정적이지 않은 외부 의존성을 가진 BDD 스펙(spec)의 특정 사용 사례에 대해 구현되었다. 이것은 웹 환경이 그랬고, 여러 레이어들 사이를 통과하기 위해 직렬화 되었었던 외부 의존성을 가진 객체들이 그랬다.

직렬화 가능한 mock을 생성하려면 MockSettings.serializable()를 사용한다:

  1. List serializableMock = mock(List.class, withSettings().serializable());

클래스에 의해 직렬화 요구사항(serialization requirements)이 정상이라 가정하고 mock은 직렬화된다.

직렬화 가능한 실제 객체의 스파이는 spy메소드가 오버로드된(overloaded) 버전을 갖고 있지 않아서 좀더 수고가 필요하다. 그렇지만 거의 사용할 일이 없으니 걱정할 필요가 없다.

  1. List list = new ArrayList(); 
      Listspy = mock(ArrayList.class, withSettings() .spiedInstance(list) .defaultAnswer(CALLS_REAL_METHODS) .serializable());
 

21. 새로운 어노테이션 : @Captor, @Spy, @InjectMocks (1.8.3 버전 부터)


  릴리즈 1.8.3에는 경우에 따라 유용한 새로운 어노테이션들이 등장했다:
  • @Captor ArgumentCaptor 생성을 단순화시킨다 - 심각한 일반화(generic) 클래스의 함수 인자를 수집하거나 컴파일러 경고를 피하기 위해 유용하다.
  • @Spy - 당신은 spy(Object) 대신 사용할 수 있다.
  • @InjectMocks - mock들을 테스트되는 객체에 자동으로 주입(inject)한다.

  모든 새로운 어노테이션은 *단지* MockitoAnnotations.initMocks(Object)로 처리한 것이다.

22. (**신규**) 타임 아웃에 대한 검증(1.8.5 버전 부터)


  시간 제한과 함께 검증이 가능하다. 동시 진행 상황(concurrent conditions)의 테스팅에 유용할 것이다. 
  이 기능은 드물게 사용될 것 같지만 - 당신의 멀티 쓰레드 상황의 시스템(multi-threaded system)에서 좀더 나은 방향을 제시할 것이라 생각했다. 
  InOrder 검증에 대해서는 아직 작동하지 않는다. 
  예제: 
  1. // someMethod()가 주어진 시간 내에 호출되면 통과 
      verify(mock, timeout(100)).someMethod();
    // 위 코드는 이렇게도 가능하다. 
      verify(mock, timeout(100).times(1)).someMethod();
    // someMethod()가 주어진 시간내에 *정확히* 2번 호출됐다면 통과 
      verify(mock, timeout(100).times(2)).someMethod();
    // someMethod()가 주어진 시간내에 *적어도* 2번 호출됐다면 통과 
      verify(mock, timeout(100).atLeast(2)).someMethod();
    // 주어진 별도의 검증 모드를 사용해서 시간내에 someMethod()를 검증 
      // 당신의 별도의 검증 모드들에 대해서만 유용함. 
      verify(mock, new Timeout(100, yourOwnVerificationMode)).someMethod();

  


Field Summary
static Answer<java.lang.Object> CALLS_REAL_METHODS
Optional Answer to be used with mock(Class, Answer)
static Answer<java.lang.Object> RETURNS_DEEP_STUBS
Optional Answer to be used with mock(Class, Answer)
static Answer<java.lang.Object> RETURNS_DEFAULTS
The default Answer of every mock if the mock was not stubbed.
static Answer<java.lang.Object> RETURNS_MOCKS
Optional Answer to be used with mock(Class, Answer)
static Answer<java.lang.Object> RETURNS_SMART_NULLS
Optional Answer to be used with mock(Class, Answer)
 
Constructor Summary
Mockito()
 
Method Summary
static VerificationMode atLeast(int minNumberOfInvocations)
Allows at-least-x verification.
static VerificationMode atLeastOnce()
Allows at-least-once verification.
static VerificationMode atMost(int maxNumberOfInvocations)
Allows at-most-x verification.
static Stubber doAnswer(Answer answer)
Use doAnswer() when you want to stub a void method with generic Answer.
static Stubber doCallRealMethod()
Use doCallRealMethod() when you want to call the real implementation of a method.
static Stubber doNothing()
Use doNothing() for setting void methods to do nothing.
static Stubber doReturn(java.lang.Object toBeReturned)
Use doReturn() in those rare occasions when you cannot use when(Object).
static Stubber doThrow(java.lang.Throwable toBeThrown)
Use doThrow() when you want to stub the void method with an exception.
static InOrder inOrder(java.lang.Object... mocks)
Creates InOrder object that allows verifying mocks in order.
static
<T> T
mock(java.lang.Class<T> classToMock)
Creates mock object of given class or interface.
static
<T> T
mock(java.lang.Class<T> classToMock, Answer defaultAnswer)
Creates mock with a specified strategy for its answers to interactions.
static
<T> T
mock(java.lang.Class<T> classToMock, MockSettings mockSettings)
Creates a mock with some non-standard settings.
static
<T> T
mock(java.lang.Class<T> classToMock, ReturnValues returnValues)
Deprecated. Please use mock(Foo.class, defaultAnswer);See mock(Class, Answer)
Why it is deprecated? ReturnValues is being replaced by Answer for better consistency & interoperability of the framework. Answer interface has been in Mockito for a while and it has the same responsibility as ReturnValues. There's no point in mainting exactly the same interfaces.
Creates mock with a specified strategy for its return values. It's quite advanced feature and typically you don't need it to write decent tests. However it can be helpful when working with legacy systems.
Obviously return values are used only when you don't stub the method call.
Foo mock = mock(Foo.class, Mockito.RETURNS_SMART_NULLS); Foo mockTwo = mock(Foo.class, new YourOwnReturnValues());
See examples in javadoc for Mockito class
static
<T> T
mock(java.lang.Class<T> classToMock, java.lang.String name)
Specifies mock name.
static VerificationMode never()
Alias to times(0), see times(int)
static VerificationMode only()
Allows checking if given method was the only one invoked.
static
<T> void
reset(T... mocks)
Smart Mockito users hardly use this feature because they know it could be a sign of poor tests.
static
<T> T
spy(T object)
Creates a spy of the real object.
static
<T> DeprecatedOngoingStubbing<T>
stub(T methodCall)
Stubs a method call with return value or an exception.
static
<T> VoidMethodStubbable<T>
stubVoid(T mock)
Deprecated. Use doThrow(Throwable) method for stubbing voids
static VerificationWithTimeout timeout(int millis)
Allows verifying with timeout.
static VerificationMode times(int wantedNumberOfInvocations)
Allows verifying exact number of invocations.
static void validateMockitoUsage()
First of all, in case of any trouble, I encourage you to read the Mockito FAQ: http://code.google.com/p/mockito/wiki/FAQ
static
<T> T
verify(T mock)
Verifies certain behavior happened once
static
<T> T
verify(T mock, VerificationMode mode)
Verifies certain behavior happened at least once / exact number of times / never.
static void verifyNoMoreInteractions(java.lang.Object... mocks)
Checks if any of given mocks has any unverified interaction.
static void verifyZeroInteractions(java.lang.Object... mocks)
Verifies that no interactions happened on given mocks.
static
<T> OngoingStubbing<T>
when(T methodCall)
Enables stubbing methods.
static MockSettings withSettings()
Allows mock creation with additional mock settings.
 
Methods inherited from class org.mockito.Matchers
any, any, anyBoolean, anyByte, anyChar, anyCollection, anyCollectionOf, anyDouble, anyFloat, anyInt, anyList, anyListOf, anyLong, anyMap, anyObject, anySet, anySetOf, anyShort, anyString, anyVararg, argThat, booleanThat, byteThat, charThat, contains, doubleThat, endsWith, eq, eq, eq, eq, eq, eq, eq, eq, eq, floatThat, intThat, isA, isNotNull, isNull, longThat, matches, notNull, refEq, same, shortThat, startsWith
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Field Detail

RETURNS_DEFAULTS

public static final Answer<java.lang.Object> RETURNS_DEFAULTS
The default Answer of every mock if the mock was not stubbed. Typically it just returns some empty value.

Answer can be used to define the return values of unstubbed invocations.

This implementation first tries the global configuration. If there is no global configuration then it uses ReturnsEmptyValues (returns zeros, empty collections, nulls, etc.)


RETURNS_SMART_NULLS

public static final Answer<java.lang.Object> RETURNS_SMART_NULLS
Optional Answer to be used with mock(Class, Answer)

Answer can be used to define the return values of unstubbed invocations.

This implementation can be helpful when working with legacy code. Unstubbed methods often return null. If your code uses the object returned by an unstubbed call you get a NullPointerException. This implementation of Answer returns SmartNull instead of null. SmartNull gives nicer exception message than NPE because it points out the line where unstubbed method was called. You just click on the stack trace.

ReturnsSmartNulls first tries to return ordinary return values (see ReturnsMoreEmptyValues) then it tries to return SmartNull. If the return type is final then plain null is returned.

ReturnsSmartNulls will be probably the default return values strategy in Mockito 2.0

Example:

Foo mock = (Foo.class, RETURNS_SMART_NULLS); //calling unstubbed method here: Stuff stuff = mock.getStuff(); //using object returned by unstubbed call: stuff.doSomething(); //Above doesn't yield NullPointerException this time! //Instead, SmartNullPointerException is thrown. //Exception's cause links to unstubbed mock.getStuff() - just click on the stack trace.

RETURNS_MOCKS

public static final Answer<java.lang.Object> RETURNS_MOCKS
Optional Answer to be used with mock(Class, Answer)

Answer can be used to define the return values of unstubbed invocations.

This implementation can be helpful when working with legacy code.

ReturnsMocks first tries to return ordinary return values (see ReturnsMoreEmptyValues) then it tries to return mocks. If the return type cannot be mocked (e.g. is final) then plain null is returned.


RETURNS_DEEP_STUBS

public static final Answer<java.lang.Object> RETURNS_DEEP_STUBS
Optional Answer to be used with mock(Class, Answer)

Example that shows how deep stub works:

Foo mock = mock(Foo.class, RETURNS_DEEP_STUBS); // note that we're stubbing a chain of methods here: getBar().getName() when(mock.getBar().getName()).thenReturn("deep"); // note that we're chaining method calls: getBar().getName() assertEquals("deep", mock.getBar().getName());
Verification API does not support 'chaining' so deep stub doesn't change how you do verification.

WARNING: This feature should rarely be required for regular clean code! Leave it for legacy code. Mocking a mock to return a mock, to return a mock, (...), to return something meaningful hints at violation of Law of Demeter or mocking a value object (a well known anti-pattern).

Good quote I've seen one day on the web: every time a mock returns a mock a fairy dies.

How deep stub work internally?

//this: Foo mock = mock(Foo.class, RETURNS_DEEP_STUBS); when(mock.getBar().getName(), "deep"); //is equivalent of Foo foo = mock(Foo.class); Bar bar = mock(Bar.class); when(foo.getBar()).thenReturn(bar); when(bar.getName()).thenReturn("deep");

This feature will not work when any return type of methods included in the chain cannot be mocked (for example: is a primitive or a final class). This is because of java type system.


CALLS_REAL_METHODS

public static final Answer<java.lang.Object> CALLS_REAL_METHODS
Optional Answer to be used with mock(Class, Answer)

Answer can be used to define the return values of unstubbed invocations.

This implementation can be helpful when working with legacy code. When this implementation is used, unstubbed methods will delegate to the real implementation. This is a way to create a partial mock object that calls real methods by default.

As usual you are going to read the partial mock warning: Object oriented programming is more less tackling complexity by dividing the complexity into separate, specific, SRPy objects. How does partial mock fit into this paradigm? Well, it just doesn't... Partial mock usually means that the complexity has been moved to a different method on the same object. In most cases, this is not the way you want to design your application.

However, there are rare cases when partial mocks come handy: dealing with code you cannot change easily (3rd party interfaces, interim refactoring of legacy code etc.) However, I wouldn't use partial mocks for new, test-driven & well-designed code.

Example:

Foo mock = mock(Foo.class, CALLS_REAL_METHODS); // this calls the real implementation of Foo.getSomething() value = mock.getSomething(); when(mock.getSomething()).thenReturn(fakeValue); // now fakeValue is returned value = mock.getSomething();
Constructor Detail

Mockito

public Mockito()
Method Detail

mock

public static <T> T mock(java.lang.Class<T> classToMock)
Creates mock object of given class or interface.

See examples in javadoc for Mockito class

 

Parameters:
classToMock - class or interface to mock
Returns:
mock object

mock

public static <T> T mock(java.lang.Class<T> classToMock, java.lang.String name)
Specifies mock name. Naming mocks can be helpful for debugging - the name is used in all verification errors.

Beware that naming mocks is not a solution for complex code which uses too many mocks or collaborators. If you have too many mocks then refactor the code so that it's easy to test/debug without necessity of naming mocks.

If you use @Mock annotation then you've got naming mocks for free! @Mock uses field name as mock name. Read more.

See examples in javadoc for Mockito class

 

Parameters:
classToMock - class or interface to mock
name - of the mock
Returns:
mock object

mock

@Deprecated public static <T> T mock(java.lang.Class<T> classToMock, ReturnValues returnValues)
Deprecated. Please use mock(Foo.class, defaultAnswer);

See mock(Class, Answer)

Why it is deprecated? ReturnValues is being replaced by Answer for better consistency & interoperability of the framework. Answer interface has been in Mockito for a while and it has the same responsibility as ReturnValues. There's no point in mainting exactly the same interfaces.

Creates mock with a specified strategy for its return values. It's quite advanced feature and typically you don't need it to write decent tests. However it can be helpful when working with legacy systems.

Obviously return values are used only when you don't stub the method call.

Foo mock = mock(Foo.class, Mockito.RETURNS_SMART_NULLS); Foo mockTwo = mock(Foo.class, new YourOwnReturnValues());

See examples in javadoc for Mockito class

 

Parameters:
classToMock - class or interface to mock
returnValues - default return values for unstubbed methods
Returns:
mock object

mock

public static <T> T mock(java.lang.Class<T> classToMock, Answer defaultAnswer)
Creates mock with a specified strategy for its answers to interactions. It's quite advanced feature and typically you don't need it to write decent tests. However it can be helpful when working with legacy systems.

It is the default answer so it will be used only when you don't stub the method call.

Foo mock = mock(Foo.class, RETURNS_SMART_NULLS); Foo mockTwo = mock(Foo.class, new YourOwnAnswer());

See examples in javadoc for Mockito class

 

Parameters:
classToMock - class or interface to mock
defaultAnswer - default answer for unstubbed methods
Returns:
mock object

mock

public static <T> T mock(java.lang.Class<T> classToMock, MockSettings mockSettings)
Creates a mock with some non-standard settings.

The number of configuration points for a mock grows so we need a fluent way to introduce new configuration without adding more and more overloaded Mockito.mock() methods. Hence MockSettings.

Listener mock = mock(Listener.class, withSettings() .name("firstListner").defaultBehavior(RETURNS_SMART_NULLS)); );
Use it carefully and occasionally. What might be reason your test needs non-standard mocks? Is the code under test so complicated that it requires non-standard mocks? Wouldn't you prefer to refactor the code under test so it is testable in a simple way?

See also withSettings()

See examples in javadoc for Mockito class

 

Parameters:
classToMock - class or interface to mock
mockSettings - additional mock settings
Returns:
mock object

spy

public static <T> T spy(T object)
Creates a spy of the real object. The spy calls real methods unless they are stubbed.

Real spies should be used carefully and occasionally, for example when dealing with legacy code.

As usual you are going to read the partial mock warning: Object oriented programming is more less tackling complexity by dividing the complexity into separate, specific, SRPy objects. How does partial mock fit into this paradigm? Well, it just doesn't... Partial mock usually means that the complexity has been moved to a different method on the same object. In most cases, this is not the way you want to design your application.

However, there are rare cases when partial mocks come handy: dealing with code you cannot change easily (3rd party interfaces, interim refactoring of legacy code etc.) However, I wouldn't use partial mocks for new, test-driven & well-designed code.

Example:

List list = new LinkedList(); List spy = spy(list); //optionally, you can stub out some methods: when(spy.size()).thenReturn(100); //using the spy calls real methods spy.add("one"); spy.add("two"); //prints "one" - the first element of a list System.out.println(spy.get(0)); //size() method was stubbed - 100 is printed System.out.println(spy.size()); //optionally, you can verify verify(spy).add("one"); verify(spy).add("two");

Important gotcha on spying real objects!

1. Sometimes it's impossible to use when(Object) for stubbing spies. Example:
List list = new LinkedList(); List spy = spy(list); //Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty) when(spy.get(0)).thenReturn("foo"); //You have to use doReturn() for stubbing doReturn("foo").when(spy).get(0);
2. Watch out for final methods. Mockito doesn't mock final methods so the bottom line is: when you spy on real objects + you try to stub a final method = trouble. What will happen is the real method will be called *on mock* but *not on the real instance* you passed to the spy() method. Typically you may get a NullPointerException because mock instances don't have fields initiated.

See examples in javadoc for Mockito class

 

Parameters:
object - to spy on
Returns:
a spy of the real object

stub

public static <T> DeprecatedOngoingStubbing<T> stub(T methodCall)
Stubs a method call with return value or an exception. E.g:
stub(mock.someMethod()).toReturn(10); //you can use flexible argument matchers, e.g: stub(mock.someMethod(anyString())).toReturn(10); //setting exception to be thrown: stub(mock.someMethod("some arg")).toThrow(new RuntimeException()); //you can stub with different behavior for consecutive method calls. //Last stubbing (e.g: toReturn("foo")) determines the behavior for further consecutive calls. stub(mock.someMethod("some arg")) .toThrow(new RuntimeException()) .toReturn("foo");

Some users find stub() confusing therefore when(Object) is recommended over stub()

//Instead of: stub(mock.count()).toReturn(10); //You can do: when(mock.count()).thenReturn(10);
For stubbing void methods with throwables see: doThrow(Throwable)

Stubbing can be overridden: for example common stubbing can go to fixture setup but the test methods can override it. Please note that overridding stubbing is a potential code smell that points out too much stubbing.

Once stubbed, the method will always return stubbed value regardless of how many times it is called.

Last stubbing is more important - when you stubbed the same method with the same arguments many times.

Although it is possible to verify a stubbed invocation, usually it's just redundant. Let's say you've stubbed foo.bar(). If your code cares what foo.bar() returns then something else breaks(often before even verify() gets executed). If your code doesn't care what get(0) returns then it should not be stubbed. Not convinced? See here.

 

Parameters:
methodCall - method call
Returns:
DeprecatedOngoingStubbing object to set stubbed value/exception

when

public static <T> OngoingStubbing<T> when(T methodCall)
Enables stubbing methods. Use it when you want the mock to return particular value when particular method is called.

Simply put: "When the x method is called then return y".

when() is a successor of deprecated stub(Object)

Examples:

when(mock.someMethod()).thenReturn(10); //you can use flexible argument matchers, e.g: when(mock.someMethod(anyString())).thenReturn(10); //setting exception to be thrown: when(mock.someMethod("some arg")).thenThrow(new RuntimeException()); //you can set different behavior for consecutive method calls. //Last stubbing (e.g: thenReturn("foo")) determines the behavior of further consecutive calls. when(mock.someMethod("some arg")) .thenThrow(new RuntimeException()) .thenReturn("foo"); //Alternative, shorter version for consecutive stubbing: when(mock.someMethod("some arg")) .thenReturn("one", "two"); //is the same as: when(mock.someMethod("some arg")) .thenReturn("one") .thenReturn("two"); //shorter version for consecutive method calls throwing exceptions: when(mock.someMethod("some arg")) .thenThrow(new RuntimeException(), new NullPointerException();
For stubbing void methods with throwables see: doThrow(Throwable)

Stubbing can be overridden: for example common stubbing can go to fixture setup but the test methods can override it. Please note that overridding stubbing is a potential code smell that points out too much stubbing.

Once stubbed, the method will always return stubbed value regardless of how many times it is called.

Last stubbing is more important - when you stubbed the same method with the same arguments many times.

Although it is possible to verify a stubbed invocation, usually it's just redundant. Let's say you've stubbed foo.bar(). If your code cares what foo.bar() returns then something else breaks(often before even verify() gets executed). If your code doesn't care what get(0) returns then it should not be stubbed. Not convinced? See here.

See examples in javadoc for Mockito class

 

Parameters:
methodCall - method to be stubbed

verify

public static <T> T verify(T mock)
Verifies certain behavior happened once

Alias to verify(mock, times(1)) E.g:

verify(mock).someMethod("some arg");
Above is equivalent to:
verify(mock, times(1)).someMethod("some arg");

Arguments passed are compared using equals() method. Read about ArgumentCaptor or ArgumentMatcher to find out other ways of matching / asserting arguments passed.

Although it is possible to verify a stubbed invocation, usually it's just redundant. Let's say you've stubbed foo.bar(). If your code cares what foo.bar() returns then something else breaks(often before even verify() gets executed). If your code doesn't care what get(0) returns then it should not be stubbed. Not convinced? See here.

See examples in javadoc for Mockito class

 

Parameters:
mock - to be verified
Returns:
mock object itself

verify

public static <T> T verify(T mock, VerificationMode mode)
Verifies certain behavior happened at least once / exact number of times / never. E.g:
verify(mock, times(5)).someMethod("was called five times"); verify(mock, atLeast(2)).someMethod("was called at least two times"); //you can use flexible argument matchers, e.g: verify(mock, atLeastOnce()).someMethod(anyString());
times(1) is the default and can be omitted

Arguments passed are compared using equals() method. Read about ArgumentCaptor or ArgumentMatcher to find out other ways of matching / asserting arguments passed.

 

Parameters:
mock - to be verified
mode - times(x), atLeastOnce() or never()
Returns:
mock object itself

reset

public static <T> void reset(T... mocks)
Smart Mockito users hardly use this feature because they know it could be a sign of poor tests. Normally, you don't need to reset your mocks, just create new mocks for each test method.

Instead of reset() please consider writing simple, small and focused test methods over lengthy, over-specified tests. First potential code smell is reset() in the middle of the test method. This probably means you're testing too much. Follow the whisper of your test methods: "Please keep us small & focused on single behavior". There are several threads about it on mockito mailing list.

The only reason we added reset() method is to make it possible to work with container-injected mocks. See issue 55 (here) or FAQ (here).

Don't harm yourself. reset() in the middle of the test method is a code smell (you're probably testing too much).

List mock = mock(List.class); when(mock.size()).thenReturn(10); mock.add(1); reset(mock); //at this point the mock forgot any interactions & stubbing

 

Type Parameters:
T -
Parameters:
mocks - to be reset

verifyNoMoreInteractions

public static void verifyNoMoreInteractions(java.lang.Object... mocks)
Checks if any of given mocks has any unverified interaction.

You can use this method after you verified your mocks - to make sure that nothing else was invoked on your mocks.

See also never() - it is more explicit and communicates the intent well.

Stubbed invocations (if called) are also treated as interactions.

A word of warning: Some users who did a lot of classic, expect-run-verify mocking tend to use verifyNoMoreInteractions() very often, even in every test method. verifyNoMoreInteractions() is not recommended to use in every test method. verifyNoMoreInteractions() is a handy assertion from the interaction testing toolkit. Use it only when it's relevant. Abusing it leads to overspecified, less maintainable tests. You can find further reading here.

This method will also detect unverified invocations that occurred before the test method, for example: in setUp(), @Before method or in constructor. Consider writing nice code that makes interactions only in test methods.

Example:

//interactions mock.doSomething(); mock.doSomethingUnexpected(); //verification verify(mock).doSomething(); //following will fail because 'doSomethingUnexpected()' is unexpected verifyNoMoreInteractions(mock);
See examples in javadoc for Mockito class

 

Parameters:
mocks - to be verified

verifyZeroInteractions

public static void verifyZeroInteractions(java.lang.Object... mocks)
Verifies that no interactions happened on given mocks.
verifyZeroInteractions(mockOne, mockTwo);
This method will also detect invocations that occurred before the test method, for example: in setUp(), @Before method or in constructor. Consider writing nice code that makes interactions only in test methods.

See also never() - it is more explicit and communicates the intent well.

See examples in javadoc for Mockito class

 

Parameters:
mocks - to be verified

stubVoid

public static <T> VoidMethodStubbable<T> stubVoid(T mock)
Deprecated. Use doThrow(Throwable) method for stubbing voids

 

//Instead of: stubVoid(mock).toThrow(e).on().someVoidMethod(); //Please do: doThrow(e).when(mock).someVoidMethod();
doThrow() replaces stubVoid() because of improved readability and consistency with the family of doAnswer() methods.

Originally, stubVoid() was used for stubbing void methods with exceptions. E.g:

stubVoid(mock).toThrow(new RuntimeException()).on().someMethod(); //you can stub with different behavior for consecutive calls. //Last stubbing (e.g. toReturn()) determines the behavior for further consecutive calls. stubVoid(mock) .toThrow(new RuntimeException()) .toReturn() .on().someMethod();
See examples in javadoc for Mockito class

 

Parameters:
mock - to stub
Returns:
stubbable object that allows stubbing with throwable

doThrow

public static Stubber doThrow(java.lang.Throwable toBeThrown)
Use doThrow() when you want to stub the void method with an exception.

Stubbing voids requires different approach from when(Object) because the compiler does not like void methods inside brackets...

Example:

doThrow(new RuntimeException()).when(mock).someVoidMethod();

 

Parameters:
toBeThrown - to be thrown when the stubbed method is called
Returns:
stubber - to select a method for stubbing

doCallRealMethod

public static Stubber doCallRealMethod()
Use doCallRealMethod() when you want to call the real implementation of a method.

As usual you are going to read the partial mock warning: Object oriented programming is more less tackling complexity by dividing the complexity into separate, specific, SRPy objects. How does partial mock fit into this paradigm? Well, it just doesn't... Partial mock usually means that the complexity has been moved to a different method on the same object. In most cases, this is not the way you want to design your application.

However, there are rare cases when partial mocks come handy: dealing with code you cannot change easily (3rd party interfaces, interim refactoring of legacy code etc.) However, I wouldn't use partial mocks for new, test-driven & well-designed code.

See also javadoc spy(Object) to find out more about partial mocks. Mockito.spy() is a recommended way of creating partial mocks. The reason is it guarantees real methods are called against correctly constructed object because you're responsible for constructing the object passed to spy() method.

Example:

Foo mock = mock(Foo.class); doCallRealMethod().when(mock).someVoidMethod(); // this will call the real implementation of Foo.someVoidMethod() mock.someVoidMethod();

See examples in javadoc for Mockito class

 

Returns:
stubber - to select a method for stubbing

doAnswer

public static Stubber doAnswer(Answer answer)
Use doAnswer() when you want to stub a void method with generic Answer.

Stubbing voids requires different approach from when(Object) because the compiler does not like void methods inside brackets...

Example:

doAnswer(new Answer() { public Object answer(InvocationOnMock invocation) { Object[] args = invocation.getArguments(); Mock mock = invocation.getMock(); return null; }}) .when(mock).someMethod();

See examples in javadoc for Mockito class

 

Parameters:
answer - to answer when the stubbed method is called
Returns:
stubber - to select a method for stubbing

doNothing

public static Stubber doNothing()
Use doNothing() for setting void methods to do nothing. Beware that void methods on mocks do nothing by default! However, there are rare situations when doNothing() comes handy:

1. Stubbing consecutive calls on a void method:

doNothing(). doThrow(new RuntimeException()) .when(mock).someVoidMethod(); //does nothing the first time: mock.someVoidMethod(); //throws RuntimeException the next time: mock.someVoidMethod();
2. When you spy real objects and you want the void method to do nothing:
List list = new LinkedList(); List spy = spy(list); //let's make clear() do nothing doNothing().when(spy).clear(); spy.add("one"); //clear() does nothing, so the list still contains "one" spy.clear();

See examples in javadoc for Mockito class

 

Returns:
stubber - to select a method for stubbing

doReturn

public static Stubber doReturn(java.lang.Object toBeReturned)
Use doReturn() in those rare occasions when you cannot use when(Object).

Beware that when(Object) is always recommended for stubbing because it is argument type-safe and more readable (especially when stubbing consecutive calls).

Here are those rare occasions when doReturn() comes handy:

1. When spying real objects and calling real methods on a spy brings side effects

List list = new LinkedList(); List spy = spy(list); //Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty) when(spy.get(0)).thenReturn("foo"); //You have to use doReturn() for stubbing: doReturn("foo").when(spy).get(0);
2. Overriding a previous exception-stubbing:
when(mock.foo()).thenThrow(new RuntimeException()); //Impossible: the exception-stubbed foo() method is called so RuntimeException is thrown. when(mock.foo()).thenReturn("bar"); //You have to use doReturn() for stubbing: doReturn("bar").when(mock).foo();
Above scenarios shows a tradeoff of Mockito's ellegant syntax. Note that the scenarios are very rare, though. Spying should be sporadic and overriding exception-stubbing is very rare. Not to mention that in general overridding stubbing is a potential code smell that points out too much stubbing.

See examples in javadoc for Mockito class

 

Parameters:
toBeReturned - to be returned when the stubbed method is called
Returns:
stubber - to select a method for stubbing

inOrder

public static InOrder inOrder(java.lang.Object... mocks)
Creates InOrder object that allows verifying mocks in order.
InOrder inOrder = inOrder(firstMock, secondMock); inOrder.verify(firstMock).add("was called first"); inOrder.verify(secondMock).add("was called second");
Verification in order is flexible - you don't have to verify all interactions one-by-one but only those that you are interested in testing in order.

Also, you can create InOrder object passing only mocks that are relevant for in-order verification.

InOrder verification is 'greedy'. You will hardly every notice it but if you want to find out more search for 'greedy' on the Mockito wiki pages.

As of Mockito 1.8.4 you can verifyNoMoreInvocations() in order-sensitive way. Read more: InOrder.verifyNoMoreInteractions()

See examples in javadoc for Mockito class

 

Parameters:
mocks - to be verified in order
Returns:
InOrder object to be used to verify in order

times

public static VerificationMode times(int wantedNumberOfInvocations)
Allows verifying exact number of invocations. E.g:
verify(mock, times(2)).someMethod("some arg");
See examples in javadoc for Mockito class

 

Parameters:
wantedNumberOfInvocations - wanted number of invocations
Returns:
verification mode

never

public static VerificationMode never()
Alias to times(0), see times(int)

Verifies that interaction did not happen. E.g:

verify(mock, never()).someMethod();

If you want to verify there were NO interactions with the mock check out verifyZeroInteractions(Object...) or verifyNoMoreInteractions(Object...)

See examples in javadoc for Mockito class

 

Returns:
verification mode

atLeastOnce

public static VerificationMode atLeastOnce()
Allows at-least-once verification. E.g:
verify(mock, atLeastOnce()).someMethod("some arg");
Alias to atLeast(1)

See examples in javadoc for Mockito class

 

Returns:
verification mode

atLeast

public static VerificationMode atLeast(int minNumberOfInvocations)
Allows at-least-x verification. E.g:
verify(mock, atLeast(3)).someMethod("some arg");
See examples in javadoc for Mockito class

 

Parameters:
minNumberOfInvocations - minimum number of invocations
Returns:
verification mode

atMost

public static VerificationMode atMost(int maxNumberOfInvocations)
Allows at-most-x verification. E.g:
verify(mock, atMost(3)).someMethod("some arg");
See examples in javadoc for Mockito class

 

Parameters:
maxNumberOfInvocations - max number of invocations
Returns:
verification mode

only

public static VerificationMode only()
Allows checking if given method was the only one invoked. E.g:
verify(mock, only()).someMethod(); //above is a shorthand for following 2 lines of code: verify(mock).someMethod(); verifyNoMoreInvocations(mock);

See also verifyNoMoreInteractions(Object...)

See examples in javadoc for Mockito class

 

Returns:
verification mode

timeout

public static VerificationWithTimeout timeout(int millis)
Allows verifying with timeout. May be useful for testing in concurrent conditions.

It feels this feature should be used rarely - figure out a better way of testing your multi-threaded system

Not yet implemented to work with InOrder verification.

//passes when someMethod() is called within given time span verify(mock, timeout(100)).someMethod(); //above is an alias to: verify(mock, timeout(100).times(1)).someMethod(); //passes when someMethod() is called *exactly* 2 times within given time span verify(mock, timeout(100).times(2)).someMethod(); //passes when someMethod() is called *at lest* 2 times within given time span verify(mock, timeout(100).atLeast(2)).someMethod(); //verifies someMethod() within given time span using given verification mode //useful only if you have your own custom verification modes. verify(mock, new Timeout(100, yourOwnVerificationMode)).someMethod();
See examples in javadoc for Mockito class

 

Parameters:
millis - - time span in millis
Returns:
verification mode

validateMockitoUsage

public static void validateMockitoUsage()
First of all, in case of any trouble, I encourage you to read the Mockito FAQ: http://code.google.com/p/mockito/wiki/FAQ

In case of questions you may also post to mockito mailing list: http://groups.google.com/group/mockito

validateMockitoUsage() explicitly validates the framework state to detect invalid use of Mockito. However, this feature is optional because Mockito validates the usage all the time... but there is a gotcha so read on.

Examples of incorrect use:

//Oups, someone forgot thenReturn() part: when(mock.get()); //Oups, someone put the verified method call inside verify() where it should be outside: verify(mock.execute()); //Oups, someone has used EasyMock for too long and forgot to specify the method to verify: verify(mock);
Mockito throws exceptions if you misuse it so that you know if your tests are written correctly. The gotcha is that Mockito does the validation next time you use the framework (e.g. next time you verify, stub, call mock etc.). But even though the exception might be thrown in the next test, the exception message contains a navigable stack trace element with location of the defect. Hence you can click and find the place where Mockito was misused.

Sometimes though, you might want to validate the framework usage explicitly. For example, one of the users wanted to put validateMockitoUsage() in his @After method so that he knows immediately when he misused Mockito. Without it, he would have known about it not sooner than next time he used the framework. One more benefit of having validateMockitoUsage() in @After is that jUnit runner will always fail in the test method with defect whereas ordinary 'next-time' validation might fail the next test method. But even though JUnit might report next test as red, don't worry about it and just click at navigable stack trace element in the exception message to instantly locate the place where you misused mockito.

Built-in runner: MockitoJUnitRunner does validateMockitoUsage() after each test method.

Bear in mind that usually you don't have to validateMockitoUsage() and framework validation triggered on next-time basis should be just enough, mainly because of enhanced exception message with clickable location of defect. However, I would recommend validateMockitoUsage() if you already have sufficient test infrastructure (like your own runner or base class for all tests) because adding a special action to @After has zero cost.

See examples in javadoc for Mockito class

 


withSettings

public static MockSettings withSettings()

Allows mock creation with additional mock settings.

Don't use it too often. Consider writing simple tests that use simple mocks. Repeat after me: simple tests push simple, KISSy, readable & maintainable code. If you cannot write a test in a simple way - refactor the code under test.

Examples of mock settings:

//Creates mock with different default answer & name Foo mock = mock(Foo.class, withSettings() .defaultAnswer(RETURNS_SMART_NULLS) .name("cool mockie")); //Creates mock with different default answer, descriptive name and extra interfaces Foo mock = mock(Foo.class, withSettings() .defaultAnswer(RETURNS_SMART_NULLS) .name("cool mockie") .extraInterfaces(Bar.class));

MockSettings has been introduced for two reasons. Firstly, to make it easy to add another mock settings when the demand comes. Secondly, to enable combining different mock settings without introducing zillions of overloaded mock() methods.

See javadoc for MockSettings to learn about possible mock settings.

 

Returns:
mock settings instance with defaults.


 

 

 

 

728x90
반응형