현재 Springboot 프로젝트에서 Mockito를 사용해 테스트 코드를 작성하고 있다. Service 계층 테스트를 작성하는데, read, update는 결과를 확인하고 delete는 verify를 사용해 호출 횟수를 확인한다. 그런데 create는.. verify로만 확인하기엔 아무래도 새로운 객체가 제대로 생성된 것이 맞는지 항상 애매한 느낌이었다. 그래서 save를 호출 할 때 전달되는 객체가 정상적으로 생성된 것인지 확인할 방법을 찾고 있었다.
ArgumentCaptor가 이에 적절한 해결책이다. ArgumentCaptor란 Mockito에서 제공하는 클래스로, 메서드 호출 시 전달되는 인자를 캡쳐할 수 있다.
먼저, ArgumentCaptor
를 사용하기 전 create 테스트 코드는 아래와 같았다.
@Test
void createProblem() {
// given
CreateProblemRequest request = CreateProblemRequest.builder()
.groupId(10L)
.link("link")
.deadline(LocalDate.now())
.build();
Problem problem = Problem.builder().studyGroup(group)
.link("link")
.deadline(LocalDate.now())
.build();
when(groupRepository.findById(10L)).thenReturn(Optional.ofNullable(group));
// when
problemService.createProblem(user,request);
// then
verify(problemRepository,times(1)).save(problem);
}
create 테스트 코드를 작성할 때, verify 한 줄로 create를 검증한다는 부분이 항상 애매한 느낌이었고 더 확실한 테스트 방법을 찾고 있었다.
이제 ArgumentCaptor
을 적용해보자면, 먼저 캡쳐 할 인자의 클래스를 가지고 ArgumentCaptor
을 생성한다.
@Captor
private ArgumentCaptor<Problem> problemCaptor;
이렇게 하면 Problem
클래스를 캡쳐하는 ArgumentCaptor
객체가 생성된 것이다.
ArgumentCaptor
에서 쓰이는 메서드는 크게 두 가지 인데,
capture()
: 해당 메서드의 인자로 들어가는 객체를 캡쳐해 ArgumentCaptor로 감싸서 갖고 있는다.getValue()
:capture()
로 캡쳐한ArgumentCaptor
객체에서 인자 객체를 추출한다.
따라서 verify의 save 메서드에 problemCaptor.capture()
를 넣어 인자를 캡쳐한 후, problemCaptor.getValue()
로 추출한 객체로 assert를 진행하면 된다.
@Test
void createProblem() {
// given
CreateProblemRequest request = CreateProblemRequest.builder()
.groupId(10L)
.link("link")
.deadline(LocalDate.now())
.build();
when(groupRepository.findById(10L)).thenReturn(Optional.ofNullable(group));
// when
problemService.createProblem(user,request);
// then
verify(problemRepository,times(1)).save(problemCaptor.capture());
Problem result = problemCaptor.getValue();
assertThat(result.getStudyGroup()).isEqualTo(group);
assertThat(result.getLink()).isEqualTo("link");
assertThat(result.getDeadline()).isEqualTo(LocalDate.now())
}
인자로 넘어간 객체를 확실하게 확인할 수 있는 테스트가 되었다. Mockito로 테스트를 작성한다면 꽤 유용하게 사용할만 하다.