Mockito는 단위 테스트를 작성할 때 유용한 도구로 실제 구현 대신 가상의 구현을 사용하여 원하는 방식대로 행동하게 만들 수 있다.
@Autowired
public MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper = new ObjectMapper();
@MockBean
private BoardService boardService;
@Test
void createBoard() throws Exception {
BoardCreateRequestDto requestDto = BoardCreateRequestDto.builder()
.boardName("boardName")
.boardColor("boardColor")
.boardInfo("boardInfo")
.build();
// 인자를 any(BoardCreateRequestDto.class)로 변경
when(boardService.createBoard(BoardCreateRequestDto.class)).thenReturn(BoardCreateResponseDto.builder()
.boardName("boardName")
.boardColor("boardColor")
.boardInfo("boardInfo")
.build());
ResultActions resultActions = mockMvc.perform(post("/api/board")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(requestDto)))
.andExpect(status().isOk())
.andDo(print())
.andExpect(jsonPath("$.boardName").value("boardName")) // 주석을 해제하여 검증 활성화
.andExpect(jsonPath("$.boardColor").value("boardColor"))
.andExpect(jsonPath("$.boardInfo").value("boardInfo"));
}
Spring Boot에서 MockMvc를 사용하여 Controller 레이어의 테스트를 진행하던 중 다음과 같은 문제에 직면했다
when(boardService.createBoard(requestDto)).thenReturn(...)
위 코드는 requestDto
객체를 인자로 받을 때 특정 값을 반환하도록 설정하고 있다.
그런데 테스트를 실행했을 때, 예상한 반환값이 나오지 않았다. 무엇이 문제였을까?
Mockito에서 when()
을 사용하여 특정 메서드 호출에 대한 반환값을 설정할 때 주어진 인자와 완벽히 일치하는 경우에만 해당 반환값이 반환된다.
이것은 객체의 참조가 아닌 내용까지 정확히 일치해야 한다는 것을 의미한다.
즉 requestDto
객체의 내부 상태가 테스트 실행 중에 변경되면 Mockito는 설정한 반환값을 반환하지 않게 된다.
@Autowired
public MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper = new ObjectMapper();
@MockBean
private BoardService boardService;
@Test
void createBoard() throws Exception {
BoardCreateRequestDto requestDto = BoardCreateRequestDto.builder()
.boardName("boardName")
.boardColor("boardColor")
.boardInfo("boardInfo")
.build();
// 인자를 any(BoardCreateRequestDto.class)로 변경
when(boardService.createBoard(any(BoardCreateRequestDto.class))).thenReturn(BoardCreateResponseDto.builder()
.boardName("boardName")
.boardColor("boardColor")
.boardInfo("boardInfo")
.build());
ResultActions resultActions = mockMvc.perform(post("/api/board")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(requestDto)))
.andExpect(status().isOk())
.andDo(print())
.andExpect(jsonPath("$.boardName").value("boardName")) // 주석을 해제하여 검증 활성화
.andExpect(jsonPath("$.boardColor").value("boardColor"))
.andExpect(jsonPath("$.boardInfo").value("boardInfo"));
}
이러한 문제를 해결하기 위해 Mockito의 any()
메서드를 사용할 수 있다.
any()
는 모든 인자를 허용한다는 것을 의미하며 특정 타입의 모든 객체를 허용하려면 any(클래스명.class)
와 같은 형태로 사용할 수 있다.
when(boardService.createBoard(any(BoardCreateRequestDto.class))).thenReturn(...)
위 코드는 BoardService
의 createBoard()
메서드가 어떠한 BoardCreateRequestDto
객체를 인자로 받든지 항상 설정한 반환값을 반환하도록 만든다.