7.2 KiB
아래는 **"스프링부트 웹플럭스 시리즈"**의 **8장: 웹플럭스에서의 테스트"**에 대한 초안입니다. 7장에서 만든 REST API를 기반으로 WebTestClient를 활용한 테스트를 다루며, 단위 테스트와 통합 테스트 예제를 포함했습니다. 코드도 간략히 유지하며 초보자가 따라 하기 쉽게 자연스러운 문체로 작성했습니다.
8. 웹플럭스에서의 테스트
7장에서 REST API를 완성했으니, 이제 제대로 작동하는지 확인해볼 차례입니다. 웹플럭스는 비동기 특성 때문에 테스트 방식이 기존 스프링 MVC와 조금 다릅니다. 이번 장에서는 WebTestClient를 사용해 웹플럭스 애플리케이션을 테스트하는 방법을 배워보겠습니다. 단위 테스트와 통합 테스트를 실습하며, 모킹과 비동기 테스트 팁도 함께 다룰게요. 준비되셨죠?
WebTestClient를 활용한 테스트 작성
WebTestClient는 웹플럭스 애플리케이션의 HTTP 엔드포인트를 테스트하기 위한 도구입니다. 실제 서버를 띄우거나 모킹된 환경에서 테스트할 수 있어 유연합니다. 먼저, 테스트 의존성이 build.gradle에 있는지 확인하세요 (3장에서 추가했어야 함):
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.projectreactor:reactor-test'
단위 테스트 예제
먼저, UserController의 로직을 단위 테스트로 검증해보겠습니다. 데이터베이스 호출을 모킹하여 컨트롤러만 테스트합니다. src/test/java/com/example/demo에 UserControllerTest 클래스를 만듭니다:
package com.example.demo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.reactive.server.WebTestClient;
import reactor.core.publisher.Mono;
import static org.mockito.Mockito.when;
@WebFluxTest(UserController.class)
public class UserControllerTest {
@Autowired
private WebTestClient webTestClient;
@MockBean
private UserRepository userRepository;
@Test
public void testGetUserById() {
User user = new User();
user.setId(1L);
user.setName("Alice");
user.setEmail("alice@example.com");
when(userRepository.findById(1L)).thenReturn(Mono.just(user));
webTestClient.get()
.uri("/users/1")
.exchange()
.expectStatus().isOk()
.expectBody(User.class)
.isEqualTo(user);
}
@Test
public void testGetUserNotFound() {
when(userRepository.findById(999L)).thenReturn(Mono.empty());
webTestClient.get()
.uri("/users/999")
.exchange()
.expectStatus().isNotFound()
.expectBody(String.class)
.isEqualTo("User with ID 999 not found");
}
}
@WebFluxTest: 컨트롤러만 테스트하도록 웹플럭스 환경을 설정.@MockBean:UserRepository를 모킹하여 실제 DB 호출을 대체.WebTestClient: GET 요청을 보내고 응답을 검증.
testGetUserById는 성공 케이스, testGetUserNotFound는 404 에러 케이스를 테스트합니다. ./gradlew test로 실행하면 결과가 콘솔에 표시됩니다.
통합 테스트 예제
이번엔 실제 데이터베이스와 연동한 통합 테스트를 해보겠습니다. src/test/java/com/example/demo에 UserControllerIntegrationTest를 추가합니다:
package com.example.demo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.reactive.server.WebTestClient;
import reactor.core.publisher.Mono;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class UserControllerIntegrationTest {
@Autowired
private WebTestClient webTestClient;
@Autowired
private UserRepository userRepository;
@Test
public void testCreateAndGetUser() {
User user = new User();
user.setName("Bob");
user.setEmail("bob@example.com");
webTestClient.post()
.uri("/users")
.body(Mono.just(user), User.class)
.exchange()
.expectStatus().isCreated()
.expectBody(User.class)
.value(savedUser -> {
webTestClient.get()
.uri("/users/" + savedUser.getId())
.exchange()
.expectStatus().isOk()
.expectBody(User.class)
.isEqualTo(savedUser);
});
}
}
@SpringBootTest: 전체 애플리케이션 컨텍스트를 로드하며, 랜덤 포트로 서버를 띄움.testCreateAndGetUser: 사용자를 생성하고, 생성된 ID로 조회까지 테스트.
이 테스트는 실제 MariaDB와 연동되므로, application.yaml의 설정이 올바른지 확인하세요.
모킹과 비동기 테스트 팁
- 모킹 활용:
Mockito로 리포지토리나 외부 서비스를 모킹하면 의존성을 줄이고 빠르게 테스트할 수 있습니다. 단위 테스트에서 유용하죠. - 비동기 처리 확인:
StepVerifier를 사용하면Mono나Flux의 비동기 흐름을 더 정밀하게 검증할 수 있습니다. 예를 들어:
@Test
public void testMonoWithStepVerifier() {
User user = new User();
user.setId(1L);
user.setName("Alice");
when(userRepository.findById(1L)).thenReturn(Mono.just(user));
Mono<User> userMono = userRepository.findById(1L);
StepVerifier.create(userMono)
.expectNext(user)
.verifyComplete();
}
StepVerifier: 리액티브 스트림의 이벤트를 단계별로 검증.
- 타임아웃 설정: 비동기 테스트가 너무 오래 걸리면 실패로 간주하도록 설정하세요.
WebTestClient에.responseTimeout(Duration.ofSeconds(5))를 추가할 수 있습니다.
테스트 실행해보기 _
./gradlew test를 실행하면 단위 테스트와 통합 테스트가 모두 실행됩니다. 콘솔에서 성공/실패 여부를 확인할 수 있습니다. 통합 테스트는 MariaDB가 실행 중이어야 하니, 서버가 켜져 있는지 체크하세요.
마무리
WebTestClient로 웹플럭스 API를 테스트하며, 단위 테스트와 통합 테스트의 차이도 경험해봤습니다. 비동기 환경에서의 테스트는 처음엔 낯설 수 있지만, 익숙해지면 애플리케이션의 안정성을 크게 높일 수 있습니다. 다음 장에서는 성능 최적화와 디버깅을 다루며, 웹플럭스를 실무에서 더 단단하게 다듬는 법을 배워보겠습니다. 테스트 작성의 재미를 느끼셨길 바랍니다!
이 장은 WebTestClient를 중심으로 실습을 구성했으며, 단위/통합 테스트와 비동기 팁을 간결히 다뤘습니다. 추가 예제나 수정이 필요하면 말씀해주세요!