[Spring] WebTestClient 사용기 - 2

민스킴·2024년 8월 29일
0

Spring

목록 보기
11/12

불만

WebTestClient를 사용하면 장점이 되게 많은 것처럼 말해서 직접 적용해서 테스트 코드를 작성해봤는데 매우 불편한 점이 많았다.
어떤 것 들이 불편했는지 공유해보려고 한다.

Spring MVC 호환이 잘 안됨

애초에 WebFlux에 포함된 프로젝트여서 그런지 호환이 안되는 이슈가 있다.
예를 들어 @SpringBootTest 어노테이션을 사용한 통합 테스트 코드를 작성한다고 해보자.

스프링 시큐리티에서 CSRF, OAuth2 기술을 사용해서 인증을 구현하고 있는 상황에 어떻게 테스트 코드를 작성해야 할까?

아래와 같이 작성하면 동작하지 않는다.


@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@DisplayName("GradeController 테스트")
public class GradeControllerTest {
    @Autowired
    private WebTestClient webTestClient;

    @Test
    @DisplayName("과제 테스트 실행 - 실패")
    void testGrade() {
        GradeRequest gradeRequest = new GradeRequest();
        gradeRequest.setSolutionId(1L);
        gradeRequest.setTestCaseId(1L);
        gradeRequest.setCode("code");

        webTestClient
                .mutateWith(csrf())  
                .mutateWith(mockOAuth2Login().oauth2User(MockKakaoUser()))
                .post()
                .uri("/api/grade/test")
                .bodyValue(gradeRequest)
                .exchange()
                .expectStatus().isOk();
    }
}

왜 동작하지 않을까? 이유는 간단하다.

.mutateWith 메서드가 Spring MVC를 기본적으로 지원하지 않는다. WebFlux와 같은 반응형 애플리케이션 설정을 의존하고 있다.

OAuth2 인증 미지원

내가 찾지 못하는 것일 수도 있는데, 눈을 씻고 찾아봐도 OAuth2 인증을 지원해주는 기능을 찾지 못했다.
.attribute 메서드를 사용해서 OAuth2 인증을 적용하라는 정보도 있었는데 적용되지 않았다.

Spring MVC에서 편리하게 통합 테스트 할 수 있는 방법을 찾지 못하였다.
직접 테스트용 Filter를 구현해서 .attribute 메서드를 사용해 csrf, OAuth2를 설정해야하는 것인지도 모르겠다. 하지만 테스트 코드에서 그렇게 하고 싶지 않았다.


결론) MockMvc 사용하면 편하다

@AutoConfigureMockMvc
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@DisplayName("GradeController - 통합 테스트")
public class GradeControllerTest {
    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private ObjectMapper objectMapper;

    @Test
    @DisplayName("과제 테스트 실행 - 실패")
    void testGrade() throws Exception {
        GradeRequest gradeRequest = new GradeRequest();
        gradeRequest.setSolutionId(1L);
        gradeRequest.setTestCaseId(1L);
        gradeRequest.setCode("code");

        OAuth2User oAuth2User = MockKakaoUser();

        mockMvc.perform(
                        post("/api/grade")
                                .contentType("application/json")
                                .content(objectMapper.writeValueAsString(gradeRequest))
                                .with(csrf())
                                .with(oauth2Login().oauth2User(oAuth2User))
                )
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.status").value(SuccessStatus.GRADE_SUCCESS.getStatus()))
                .andExpect(jsonPath("$.message").value(SuccessStatus.GRADE_SUCCESS.getMessage()))
                .andExpect(jsonPath("$.data").isNotEmpty());
    }
}

그냥 할 줄 아는거 사용하니까 너무 편하다.
WebTestClient를 통합 테스트에 사용하는 것은 한동안 미뤄야겠다.


참고

https://github.com/spring-projects/spring-security/issues/9257

profile
Boys, be ambitious!

0개의 댓글