Spring Mockito when() 메서드 바디 비어있는 문제 해결

song yuheon·2023년 9월 22일
0

Trouble Shooting

목록 보기
17/57
post-thumbnail

Mockito란?

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(...)

위 코드는 BoardServicecreateBoard() 메서드가 어떠한 BoardCreateRequestDto 객체를 인자로 받든지 항상 설정한 반환값을 반환하도록 만든다.


profile
backend_Devloper

0개의 댓글