90DAYS) [Pre-Project] - QuestionControllerSliceTest 작성

nacSeo (낙서)·2023년 2월 25일

Member와 Answer를 담당하는 조원분들이 다른 부분을 하시고 계시기에.. 나는 API 문서화를 하기 위한 테스트 코드를 작성하기로 했다! 내가 Question으로 테스트 코드를 작성해두면 작성해둔 코드를 기반으로 보고 작성하시는 걸로..!

테스팅 파트 때 학습한 Slice 테스트와 Mockito를 활용하여 테스트 코드를 작성했다.

@SpringBootTest
@AutoConfigureMockMvc
public class QuestionControllerTest {
    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private Gson gson;

    @MockBean
    private QuestionService questionService;

    @Autowired
    private QuestionMapper mapper;

    @Test
    void postQuestionTest() throws Exception {
        // given
        QuestionDto.Post post = new QuestionDto.Post("제목", "내용", 1L);

        Question question = mapper.questionPostDtoToQuestion(post);
        question.setId(1L);

        given(questionService.createQuestion(Mockito.any(Question.class), eq(1L)))
                .willReturn(question);

        String content = gson.toJson(post);

        // when
        ResultActions actions =
                mockMvc.perform(
                        post("/questions")
                                .accept(MediaType.APPLICATION_JSON)
                                .contentType(MediaType.APPLICATION_JSON)
                                .content(content)
                );

        // then
        actions.andExpect(status().isCreated());
    }

    @Test
    void patchQuestionTest() throws Exception {
        // given
        QuestionDto.Patch patch = new QuestionDto.Patch(1L, "질문", "내용");

        Question question = mapper.questionPatchDtoToQuestion(patch);

        given(questionService.updateQuestion(Mockito.any(Question.class)))
                .willReturn(question);

        String content = gson.toJson(patch);

        // when
        ResultActions actions =
                mockMvc.perform(
                        patch("/questions/" + question.getId())
                                .accept(MediaType.APPLICATION_JSON)
                                .contentType(MediaType.APPLICATION_JSON)
                                .content(content)
                );

        // then
        actions.andExpect(status().isMovedPermanently());
    }

    @Test
    void getQuestionTest() throws Exception {
        // given
        Question question = new Question("질문", "내용");
        question.setId(1L);

        given(questionService.findQuestion(Mockito.anyLong()))
                .willReturn(question);

        // when / when
        mockMvc.perform(
                get("/questions/" + question.getId())
                        .accept(MediaType.APPLICATION_JSON)
                        .contentType(MediaType.APPLICATION_JSON)
        )
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.data.title").value(question.getTitle()))
                .andExpect(jsonPath("$.data.contents").value(question.getContents()));
    }

    @Test
    void getQuestionsTest() throws Exception {
        // given
        Question question1 = new Question("제목1", "내용1");

        Question question2 = new Question("제목2", "내용2");

        Page<Question> pageQuestions =
                new PageImpl<>(List.of(question1, question2),
                        PageRequest.of(0, 10, Sort.by("id").descending()), 2);

        given(questionService.findQuestions(Mockito.anyInt(), Mockito.anyInt()))
                .willReturn(pageQuestions);

        String page = "1";
        String size = "10";
        MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
        queryParams.add("page", page);
        queryParams.add("size", size);

        // when
        ResultActions actions =
                mockMvc.perform(
                        get("/questions")
                                .params(queryParams)
                                .accept(MediaType.APPLICATION_JSON)
                );

        // then
        MvcResult result = actions
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.data").isArray())
                .andReturn();

        List list = JsonPath.parse(result.getResponse().getContentAsString()).read("$.data");

        assertThat(list.size(), is(2));
    }

    @Test
    void deleteQuestionTest() throws Exception {
        // given
        Long questionId = 1L;

        doNothing().when(questionService).deleteQuestion(questionId);

        // when
        ResultActions actions = mockMvc.perform(
                delete("/questions/" + questionId)
        );

         // when
        actions.andExpect(status().isNoContent());
    }
}

여러 시행착오 끝에 나온 코드다.
테스트는 다 통과되지만, 아직 뭔가 부족한 느낌의 코드다 🤔 내일 API 문서화를 진행하면서 좀 더 보충하며 수정해봐야겠다.

profile
백엔드 개발자 김창하입니다 🙇‍♂️

0개의 댓글