WebTestClient를 사용하여 WebFlux 애플리케이션을 테스트 하기

김기현·2025년 8월 6일

Spring WebFlux

목록 보기
24/28

WebTestClient를 사용해 WebFlux 애플리케이션을 테스트 하는 방법은 크게 두 가지이다.

  1. 실제 HTTP 서버를 실행하지 않고 테스트하기: 애플리케이션 컨텍스르틀 로드하지만 실제 서버는 시작하지 않고 MockMvc처럼 Mock 객체를 이용해 테스트한다.
  2. 실제 HTTP 서버를 실행하고 테스트하기: 애플리케이션을 포트에서 실행하고 실제 HTTP 요청을 보내 테스트한다.

1. Mock 객체를 사용한 테스트

이 방법은 실제 서버를 띄우지 않아 테스트 속도가 빠르고 리소스 소모가 적다. @WebFluxTest애노테이션을 사용하여 특정 컨트롤러만 로드하고 테스트할 수 있다.

주요 단계

  1. @WebFluxTest사용: 테스트할 컨트롤러와 클래스를 지정한다.
  2. @AutowiredWebTestClient주입: Spring이 테스트 환경에 맞게 자동 구성한 WebTestClient를 주입받는다.

코드

@WebFluxTest(UserController.class) // UserController만 테스트
class UserControllerTest {

    @Autowired
    private WebTestClient webTestClient;

    @Test
    void testGetUserById() {
        // GET 요청 수행
        webTestClient.get().uri("/users/{id}", "1")
            .exchange()             // 요청 실행
            .expectStatus().isOk()  // HTTP 상태 코드가 200인지 검증
            .expectBody(User.class) // 응답 본문 타입을 User 클래스로 검증
            .value(user -> {        // 응답 본문 값 검증
                assert user.getId().equals("1");
                assert user.getName().equals("Test User");
            });
    }
}

2. 실제 서버를 사용한 테스트

이 방법은 HTTP 요청-응답의 전체 흐름을 테스트하므로 실제 배포 환경과 가장 유사한 테스트를 수행할 수 있다. @SpringBootTestWebTestClient.Builder를 사용한다.

주요 단계

  1. @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)사용: 무작이 포트에서 실제 서버를 실행한다.
  2. @LocalServerPort로 포트 번호 주입: 서버가 실행된 포트 번호를 가져온다.
  3. WebTestClient.Builder로 클라이언트 생성: 기본 URL을 설정하여 WebTestClient인스턴스를 만든다.

코드

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class FullApplicationTest {

    @LocalServerPort
    private int port;

    private WebTestClient webTestClient;

    @BeforeEach
    void setup() {
        // 실제 포트를 기반으로 WebTestClient 초기화
        this.webTestClient = WebTestClient.bindToServer()
            .baseUrl("http://localhost:" + port)
            .build();
    }

    @Test
    void testFullFlow() {
        webTestClient.get().uri("/api/data")
            .exchange()
            .expectStatus().isOk()
            .expectBodyList(String.class)
            .hasSize(2)
            .contains("item1", "item2");
    }
}

주요 WebTestClient 메소드

public interface WebTestClient {

    // GET 요청을 시작합니다. 리소스 조회에 사용됩니다.
    RequestHeadersUriSpec<?> get();

    // HEAD 요청을 시작합니다. GET 요청과 동일하지만, 응답 본문 없이 헤더 정보만 가져올 때 사용됩니다.
    RequestHeadersUriSpec<?> head();

    // POST 요청을 시작합니다. 새로운 리소스를 생성할 때 사용됩니다.
    RequestBodyUriSpec post();

    // PUT 요청을 시작합니다. 기존 리소스를 완전히 대체하거나 생성할 때 사용됩니다.
    RequestBodyUriSpec put();

    // PATCH 요청을 시작합니다. 리소스의 일부를 업데이트할 때 사용됩니다.
    RequestBodyUriSpec patch();

    // DELETE 요청을 시작합니다. 리소스를 삭제할 때 사용됩니다.
    RequestHeadersUriSpec<?> delete();

    // OPTIONS 요청을 시작합니다. 특정 URL에서 지원하는 HTTP 메서드를 조회할 때 사용됩니다.
    RequestHeadersUriSpec<?> options();

    // 위에 정의되지 않은 HTTP 메서드(예: TRACE)를 포함한 모든 HTTP 요청을 시작할 수 있는 범용 메서드입니다.
    RequestBodyUriSpec method(HttpMethod method);
}
profile
백엔드 개발자를 목표로 공부하는 대학생

0개의 댓글