메소드 호출 시 사용된 인자를 매칭 및 검증하는 데 사용되는 유틸이다.
@Mock
private BookRepository bookRepository;
@InjectMocks
private BookService bookService;
@Test
public void addTest_1() {
// 인자 생성
Book entity = Book.create("재밌는책", "저자");
// 엔티티 저장 메소드 호출
bookService.add(entity);
// save 메소드가 어떤 Book 객체든 전달된 채로 1번 호출되었는지 확인
Mockito.verify(bookRepository, Mockito.times(1)).save(ArgumentMatchers.any(Book.class));
}
any() - 모든 값이든 허용any(Class<T> type) - 특정 클래스면 모두 허용eq(T value) - 정확히 일치하는 값isNull() - null 값isNotNull() - null이 아닌 값argThat(Matcher<T> matcher) - 커스텀 매처 사용ArgumentMatchers 외에 추가적인 조건을 제공하는 유틸이다.
EasyMock과 호환성을 위해 유지된다고하며 ArgumentMatchers를 사용해 스텁 및 확인을 간단하게 유지하는 것이 좋다고 주석에 나와있다.
@Test
public void getByIdTest_1() {
// 10L Id의 Book 조회
bookService.getById(10L);
// 전달된 Id가 5보다 큰 값이였는지 확인
Mockito.verify(bookRepository).findById(AdditionalMatchers.gt(5L));
}
@Test
public void getByIdTest_2() {
// 10L Id의 Book 조회
bookService.getById(10L);
// 전달된 Id가 10보다 작거나 같은 값이였는지 확인
Mockito.verify(bookRepository).findById(AdditionalMatchers.leq(10L));
}
static import 해봐도 가독성이 그닥 좋지않아보인다.
왜 추천하지 않는지 알겠다.
gt(T value) - 주어진 값보다 크면 허용lt(T value) - 주어진 값보다 작으면 허용geq(T value) - 주어진 값보다 크거나 같으면 허용leq(T value) - 주어진 값보다 작거나 같으면 허용cmpEq(T value) - 주어진 값과 compareTo로 비교한 동등 객체면 허용Mockito에서 메소드 호출 시 전달된 인자를 캡처하여 나중에 검증할 수 있도록 도와주는 유틸이다.
Warning (클래스 주석에 있는 경고)
ArgumentCaptor를 검증과 함께 사용하는 것이 좋지만 스텁과 함께 사용하는 것은 권장되지 않습니다.
스텁과 함께 ArgumentCaptor를 사용하면 캡터가 assert (일명 verify 또는 'then') 블록 외부에서 생성되기 때문에 테스트 가독성이 떨어질 수 있습니다.
또한 스텁 된 메소드가 호출되지 않으면 인수가 캡처되지 않기 때문에 결함 지역화를 줄일 수 있습니다.
@Test
public void addTest_2() {
// 인자 생성
Book entity = Book.create("재밌는책", "저자");
// 엔티티 저장 메소드 호출
bookService.add(entity);
// 캡처 생성
ArgumentCaptor<Book> entityCaptor = ArgumentCaptor.forClass(Book.class);
// bookRepository.save() 메소드가 1번 호출되었는지 확인하고 인자 캡처
Mockito.verify(bookRepository, Mockito.times(1)).save(entityCaptor.capture());
// 캡처된 인자 값 검증
Assertions.assertEquals(entity, entityCaptor.getValue());
}
forClass(Class<T> clazz) - 특정 클래스의 캡처를 생성capture() - 인수를 캡처 (verification안에서 사용, return: null or defaultValues)getValue() - 캡처된 단일 인자를 반환getAllValues() - 캡처된 여러 인자를 반환Mockito 메소드 호출 시 메소드의 행위를 동적인 관리가 가능하게 도와주는 유틸이다.
@Test
public void addTest_3() {
// save() 호출 시 첫번째 인자를 그대로 반환
Mockito.when(bookRepository.save(ArgumentMatchers.any())).then(AdditionalAnswers.returnsFirstArg());
// 엔티티 저장 메소드 호출
Book entity = Book.create("재밌는책", "저자");
Book savedEntity = bookService.add(entity);
// 인자 객체와 반환 객체가 같은지 확인
Assertions.assertEquals(entity, savedEntity);
}
returnsFirstArg() - 메소드 호출 시 첫번째 인자를 반환returnsSecondArg() - 메소드 호출 시 두번째 인자를 반환answersWithDelay(Long delay, Answer answer) - 메소드 호출 시 ms만큼 지연 후 동작delegatesTo(Object delegate) - 특정 객체로 메소드 호출을 위임