[spring/test]Controller 테스트

kongta2·2023년 12월 7일

@WebMvcTest를 이용한 Controller 테스트

TodoControllerTest - Controller 기능 구현

@WebMvcTest(TodoController.class)
class TodoControllerTest extends ControllerTest implements TodoTest {

    @MockBean
    private TodoService todoService;

    @DisplayName("할일 생성 요청")
    @Test
    void postTodo() throws Exception {
        // given

        // when
        var action = mockMvc.perform(post("/api/todos")
                .contentType(MediaType.APPLICATION_JSON)
                .accept(MediaType.APPLICATION_JSON)
                .content(objectMapper.writeValueAsString(TEST_TODO_REQUEST_DTO)));

        // then
        action.andExpect(status().isCreated());
        verify(todoService, times(1)).createTodo(any(TodoRequestDto.class), eq(TEST_USER));
    }


    @Nested
    @DisplayName("할일 조회 요청")
    class getTodo {
        @DisplayName("할일 조회 요청 성공")
        @Test
        void getTodo_success() throws Exception {
            // given
            given(todoService.getTodoDto(eq(TEST_TODO_ID))).willReturn(TEST_TODO_RESPONSE_DTO);

            // when
            var action = mockMvc.perform(get("/api/todos/{todoId}", TEST_TODO_ID)
                    .accept(MediaType.APPLICATION_JSON));

            // then
            action
                    .andExpect(status().isOk())
                    .andExpect(jsonPath("$.title").value(TEST_TODO_TITLE))
                    .andExpect(jsonPath("$.content").value(TEST_TODO_CONTENT));
        }

        @DisplayName("할일 조회 요청 실패 - 존재하지 않는 할일ID")
        @Test
        void getTodo_fail_todoIdNotExist() throws Exception {
            // given
            given(todoService.getTodoDto(eq(TEST_TODO_ID))).willThrow(new IllegalArgumentException());

            // when
            var action = mockMvc.perform(get("/api/todos/{todoId}", TEST_TODO_ID)
                    .accept(MediaType.APPLICATION_JSON));

            // then
            action
                    .andExpect(status().isBadRequest());
        }
    }

    @DisplayName("할일 목록 조회 요청")
    @Test
    void getTodoList() throws Exception {
        // given
        var testTodo1 = TodoTestUtils.get(TEST_TODO, 1L, LocalDateTime.now(), TEST_USER);
        var testTodo2 = TodoTestUtils.get(TEST_TODO, 2L, LocalDateTime.now().minusMinutes(1), TEST_USER);
        var testAnotherTodo = TodoTestUtils.get(TEST_TODO, 3L, LocalDateTime.now(), TEST_ANOTHER_USER);

        given(todoService.getUserTodoMap()).willReturn(
                Map.of(new UserDto(TEST_USER), List.of(new TodoResponseDto(testTodo1), new TodoResponseDto(testTodo2)),
                        new UserDto(TEST_ANOTHER_USER), List.of(new TodoResponseDto(testAnotherTodo))));

        // when
        var action = mockMvc.perform(get("/api/todos")
                .accept(MediaType.APPLICATION_JSON));

        // then
        action
                .andExpect(status().isOk())
                .andExpect(jsonPath("$[?(@.user.username=='" + TEST_USER.getUsername() + "')].todoList[*].id")
                        .value(Matchers.containsInAnyOrder(testTodo1.getId().intValue(), testTodo2.getId().intValue())))
                .andExpect(jsonPath("$[?(@.user.username=='" + TEST_ANOTHER_USER.getUsername() + "')].todoList[*].id")
                        .value(Matchers.containsInAnyOrder(testAnotherTodo.getId().intValue())));
        verify(todoService, times(1)).getUserTodoMap();
    }

    @Nested
    @DisplayName("할일 수정 요청")
    class putTodo {
        @DisplayName("할일 수정 요청 성공")
        @Test
        void putTodo_success() throws Exception {
            // given
            given(todoService.updateTodo(eq(TEST_TODO_ID), eq(TEST_TODO_REQUEST_DTO), any(User.class))).willReturn(TEST_TODO_RESPONSE_DTO);

            // when
            var action = mockMvc.perform(put("/api/todos/{todoId}", TEST_TODO_ID)
                    .contentType(MediaType.APPLICATION_JSON)
                    .accept(MediaType.APPLICATION_JSON)
                    .content(objectMapper.writeValueAsString(TEST_TODO_REQUEST_DTO)));

            // then
            action
                    .andExpect(status().isOk())
                    .andExpect(jsonPath("$.title").value(TEST_TODO_TITLE))
                    .andExpect(jsonPath("$.content").value(TEST_TODO_CONTENT));
        }

        @DisplayName("할일 수정 요청 실패 - 권한 없음")
        @Test
        void putTodo_fail_rejected() throws Exception {
            // given
            given(todoService.updateTodo(eq(TEST_TODO_ID), eq(TEST_TODO_REQUEST_DTO), any(User.class))).willThrow(new RejectedExecutionException());

            // when
            var action = mockMvc.perform(put("/api/todos/{todoId}", TEST_TODO_ID)
                    .contentType(MediaType.APPLICATION_JSON)
                    .accept(MediaType.APPLICATION_JSON)
                    .content(objectMapper.writeValueAsString(TEST_TODO_REQUEST_DTO)));

            // then
            action
                    .andExpect(status().isBadRequest());
        }

        @DisplayName("할일 수정 요청 실패 - 존재하지 않는 할일ID")
        @Test
        void putTodo_fail_illegalArgument() throws Exception {
            // given
            given(todoService.updateTodo(eq(TEST_TODO_ID), eq(TEST_TODO_REQUEST_DTO), any(User.class))).willThrow(new IllegalArgumentException());

            // when
            var action = mockMvc.perform(put("/api/todos/{todoId}", TEST_TODO_ID)
                    .contentType(MediaType.APPLICATION_JSON)
                    .accept(MediaType.APPLICATION_JSON)
                    .content(objectMapper.writeValueAsString(TEST_TODO_REQUEST_DTO)));

            // then
            action
                    .andExpect(status().isBadRequest());
        }
    }

    @Nested
    @DisplayName("할일 완료 요청")
    class completeTodo {
        @DisplayName("할일 완료 요청 성공")
        @Test
        void completeTodo_success() throws Exception {
            // given
            TEST_TODO_RESPONSE_DTO.setIsCompleted(true);
            given(todoService.completeTodo(eq(TEST_TODO_ID), any(User.class))).willReturn(TEST_TODO_RESPONSE_DTO);

            // when
            var action = mockMvc.perform(patch("/api/todos/{todoId}/complete", TEST_TODO_ID)
                    .accept(MediaType.APPLICATION_JSON));

            // then
            action
                    .andExpect(status().isOk())
                    .andExpect(jsonPath("$.title").value(TEST_TODO_TITLE))
                    .andExpect(jsonPath("$.content").value(TEST_TODO_CONTENT))
                    .andExpect(jsonPath("$.isCompleted").value(true));
        }

        @DisplayName("할일 완료 요청 실패 - 권한 없음")
        @Test
        void completeTodo_fail_rejected() throws Exception {
            // given
            given(todoService.completeTodo(eq(TEST_TODO_ID), any(User.class))).willThrow(new RejectedExecutionException());

            // when
            var action = mockMvc.perform(patch("/api/todos/{todoId}/complete", TEST_TODO_ID)
                    .accept(MediaType.APPLICATION_JSON));

            // then
            action
                    .andExpect(status().isBadRequest());
        }

        @DisplayName("할일 완료 요청 실패 - 존재하지 않는 할일ID")
        @Test
        void completeTodo_fail_illegalArgument() throws Exception {
            // given
            given(todoService.completeTodo(eq(TEST_TODO_ID), any(User.class))).willThrow(new IllegalArgumentException());

            // when
            var action = mockMvc.perform(patch("/api/todos/{todoId}/complete", TEST_TODO_ID)
                    .accept(MediaType.APPLICATION_JSON));

            // then
            action
                    .andExpect(status().isBadRequest());
        }
    }

}

profile
2025.04.01~

0개의 댓글