argThat
과 ArgumentMatcher를 조합하여 동적인 인자 비교가 가능하다. when
과 verify
에서 모두 사용가능하다.
이를 사용하면 특히 테스트 대상 메소드 내부에서 직접 new
로 생성한 값에 대해 when
에서 ArgumentCaptor
없이 비교가능하여 불필요한 verify
호출을 줄일 수 있다.
ArgumentMatcher 문서를 참조하면 된다.
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()));
가능하면 argThat
부분을 메소드로 빼서 인자를 받아 ArgumentMatcher를 구성하는 것이 좋다. 아래는 문자열 List를 인자로 받을 때, 해당 리스트의 값이 모두 포함돼 있는지 검사하는 Matcher.
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); } }); }
when
에서 동일한 모의 객체의 동일한 메소드를 두 번이상 argThat
으로 호출하면 오류가 발생할 수 있다. 이 때는 doReturn
방식으로 when
을 구성한다.
doReturn(리턴값).when(mockObject).mockMethod(argThat(....));
// MockitoRunner 사용시 @Captor ArgumentCaptor<MyClass> myClassCaptor; // 코드로 직접 지정 ArgumentCaptor<MyClass> myClassCaptor = ArgumentCaptor.forClass(MyClass.class);
@RunWIth
없이 일괄 @Mock
객체 생성하기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 애노테이션 붙은 필드에 객체들이 생서됨 ... } }
@ExtendWith(MockitoExtension.class) class UserServiceTest { @Mockito ... } // Strictness 를 설정하려면 아래 추가. default가 STRICT_STUBS임. LENIENT 로 변경하기 @MockitoSettings(strictness = Strictness.LENIENT)
LENIENT
는 좋지 잘못된 stub 을 만들고 있다는 의미가 되므로 가급적 STRICT_STUB
(기본값)을 유지할것.3.4.0
이상 버전 지원LocalDateTime.now()
테스트 등에 좋다.try-with-resources
로 감싸서 할 것.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());
when(LocalDateTime.from(Mockito.any())).thenCallRealMethod();
try-with-resources
로 감싸서 할 것.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());