사용자 도구

사이트 도구


java:mockito

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

다음 판
이전 판
java:mockito [2012/07/05 10:31]
kwon37xi 새로 만듦
java:mockito [2023/11/30 14:17] (현재)
kwon37xi [mockStatic]
줄 1: 줄 1:
 ====== Mockito ====== ====== Mockito ======
-  * [[http://code.google.com/p/mockito/|Mockito]] +  * [[https://github.com/mockito/mockito|Mockito]] 
-  * [[http://refcardz.dzone.com/refcardz/mockito#refcard-download-social-buttons-display|Mockito RefCard]]+  * https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html 
 +  * [[https://dzone.com/refcardz/mockito|Mockito RefCard]] 
 +  * [[https://examples.javacodegeeks.com/core-java/mockito/mockito-tutorial-beginners/|Mockito Tutorial for beginners]]
  
 +===== argThat =====
 +''argThat''과 [[http://mockito.github.io/mockito/docs/current/org/mockito/ArgumentMatcher.html|ArgumentMatcher]]를 조합하여 동적인 인자 비교가 가능하다. ''when''과 ''verify''에서 모두 사용가능하다.
 +
 +이를 사용하면 특히 테스트 대상 메소드 내부에서 직접 ''new''로 생성한 값에 대해 ''when''에서 ''ArgumentCaptor''없이 비교가능하여 불필요한 ''verify''호출을 줄일 수 있다.
 +
 +[[http://mockito.github.io/mockito/docs/current/org/mockito/ArgumentMatcher.html|ArgumentMatcher]] 문서를 참조하면 된다.
 +<code java>
 +class IsListOfTwoElements extends ArgumentMatcher<List> {
 +    public boolean matches(Object list) {
 +        return ((List) list).size() == 2;
 +    }
 +}
 +List mock = mock(List.class);
 +
 +when(mock.addAll(argThat(new IsListOfTwoElements()))).thenReturn(true);
 +
 +mock.addAll(Arrays.asList("one", "two"));
 +
 +verify(mock).addAll(argThat(new IsListOfTwoElements()));
 +</code>
 +
 +가능하면 ''argThat'' 부분을 메소드로 빼서 인자를 받아 ArgumentMatcher를 구성하는 것이 좋다. 아래는 문자열 List를 인자로 받을 때, 해당 리스트의 값이 모두 포함돼 있는지 검사하는 Matcher.
 +<code java>
 +private List<String> sameStringList(final Collection<String> strings) {
 +    return argThat(new ArgumentMatcher<List<String>>() {
 +        @Override
 +        public boolean matches(Object argument) {
 +            List<String> args = (List<String>) argument;
 +            return args.size() == strings.size() && args.containsAll(strings);
 +        }
 +    });
 +}
 +</code>
 +
 +''when''에서 동일한 모의 객체의 동일한 메소드를 두 번이상 ''argThat''으로 호출하면 오류가 발생할 수 있다. 이 때는 ''doReturn'' 방식으로 ''when''을 구성한다.
 +<code java>
 +doReturn(리턴값).when(mockObject).mockMethod(argThat(....));
 +</code>
 +
 +===== ArgumentCaptor =====
 +  * [[https://www.baeldung.com/mockito-argumentcaptor|Using Mockito ArgumentCaptor | Baeldung]]
 +
 +<code java>
 +// MockitoRunner 사용시
 +@Captor
 +ArgumentCaptor<MyClass> myClassCaptor;
 +
 +// 코드로 직접 지정
 +ArgumentCaptor<MyClass> myClassCaptor = ArgumentCaptor.forClass(MyClass.class);
 +</code>
 +===== initMocks =====
 +  * [[https://examples.javacodegeeks.com/core-java/mockito/initializing-mockito-with-initmocks/|Initializing Mockito with InitMocks]]
 +  * ''@RunWIth''없이 일괄 ''@Mock'' 객체 생성하기
 +<code java>
 +public class CalculatorApplicationTestInitMocks {
 +    @Mock private Adder adderMock;
 +    @Mock private Subtracter subtracterMock;
 +    @Mock private Multiplier multiplierMock;
 +    @Mock private Divisor divisorMock;
 +
 +    @Before
 +    public void setUp() {
 +        MockitoAnnotations.initMocks(this); // 테스트 클래스의 @Mock 애노테이션 붙은 필드에 객체들이 생서됨
 +        ...
 +    }
 +}
 +</code>
 +
 +===== JUnit 5 =====
 +  * [[java:junit:5|JUnit 5]]와 함께 사용.
 +  * [[https://www.baeldung.com/mockito-junit-5-extension|Mockito and JUnit 5 - Using ExtendWith | Baeldung]]
 +
 +<code java>
 +@ExtendWith(MockitoExtension.class)
 +class UserServiceTest {
 +    @Mockito ...
 +}
 +
 +// Strictness 를 설정하려면 아래 추가. default가 STRICT_STUBS임. LENIENT 로 변경하기
 +@MockitoSettings(strictness = Strictness.LENIENT)
 +</code>
 +  * ''LENIENT''는 좋지 잘못된 stub 을 만들고 있다는 의미가 되므로 가급적 ''STRICT_STUB''(기본값)을 유지할것.
 +===== mockStatic =====
 +  * Mockito ''3.4.0'' 이상 버전 지원
 +  * static method mocking. 특히 ''LocalDateTime.now()'' 테스트 등에 좋다.
 +  * [[https://www.baeldung.com/mockito-mock-static-methods|Mocking Static Methods With Mockito | Baeldung]]
 +  * 항상 ''try-with-resources''로 감싸서 할 것.
 +
 +
 +<code java>
 +import static org.mockito.Mockito.mockStatic;
 +
 +assertEquals("foo", Foo.method());
 +try (MockedStatic<Foo> mocked = mockStatic(Foo.class)) {
 +    mocked.when(Foo::method).thenReturn("bar");
 +    // 혹은 Mockito.when(Foo.method()).thenReturn("bar");
 +    assertEquals("bar", Foo.method());
 +    mocked.verify(Foo::method);
 +}
 +assertEquals("foo", Foo.method());
 +</code>
 +  * 만약 mocking 할 필요가 없는 다른 static method가 호출된다면 실제 코드를 호출하게 명시적으로 지정해야 한다.
 +<code java>
 +when(LocalDateTime.from(Mockito.any())).thenCallRealMethod();
 +</code>
 +===== mockConstruction =====
 +  * 생성자 mocking
 +  * 항상 ''try-with-resources''로 감싸서 할 것.
 +
 +
 +<code java>
 + assertEquals("foo", new Foo().method());
 + try (MockedConstruction mocked = mockConstruction(Foo.class)) {
 + Foo foo = new Foo();
 + when(foo.method()).thenReturn("bar");
 + assertEquals("bar", foo.method());
 + verify(foo).method();
 + }
 + assertEquals("foo", new Foo().method());
 + 
 +</code>
 +
 +===== 참고 =====
 +  * [[http://www.javacodegeeks.com/2015/11/mockito-verification.html|Mockito Verification]]
 +  * [[http://www.javacodegeeks.com/2015/11/testing-with-mockito.html|Mockito Tutorial: Testing and Mocking with Mockito]]
 +  * [[http://www.javacodegeeks.com/2015/12/using-mockito-without-static-imports-java-8.html|Using Mockito without static imports with Java 8]]
 +  * [[https://www.baeldung.com/mockito-core-vs-mockito-all|The Difference Between mockito-core and mockito-all | Baeldung]]
 +  * [[https://www.baeldung.com/mockito-spy|Mockito using Spy]]
 +  * [[https://www.baeldung.com/mockito-argument-matchers|Mockito ArgumentMatchers | Baeldung]]
 +  * [[https://www.baeldung.com/mockito-mock-static-methods|Mocking Static Methods With Mockito | Baeldung]]
 +  * [[https://www.baeldung.com/java-override-system-time|Overriding System Time for Testing in Java | Baeldung]]
java/mockito.1341451866.txt.gz · 마지막으로 수정됨: 2012/07/05 10:31 저자 kwon37xi