middle
Как использовать WebTestClient для тестирования реактивных и обычных приложений?
WebTestClient — клиент для тестирования веб-приложений, поддерживающий как реактивные (WebFlux), так и классические (MVC) приложения. Предоставляет fluent API для выполнения запросов и проверки ответов.
С SpringBootTest (реальный сервер)
Пример кода
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class UserControllerWebClientTest {
@Autowired
private WebTestClient webTestClient;
@Test
void shouldGetAllUsers() {
webTestClient.get()
.uri("/api/users")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk()
.expectBodyList(UserDto.class)
.hasSize(3)
.contains(new UserDto(1L, "Иван"));
}
@Test
void shouldCreateUser() {
UserDto newUser = new UserDto(null, "Пётр");
webTestClient.post()
.uri("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(newUser)
.exchange()
.expectStatus().isCreated()
.expectBody(UserDto.class)
.value(user -> {
assertNotNull(user.getId());
assertEquals("Пётр", user.getName());
});
}
@Test
void shouldReturnNotFound() {
webTestClient.get()
.uri("/api/users/999")
.exchange()
.expectStatus().isNotFound();
}
}
Работа с JSON-телом ответа
Пример
@Test
void shouldVerifyResponseBody() {
webTestClient.get()
.uri("/api/users/1")
.exchange()
.expectStatus().isOk()
.expectBody()
.jsonPath("$.name").isEqualTo("Иван")
.jsonPath("$.email").isNotEmpty()
.jsonPath("$.id").isNumber();
}
С заголовками и аутентификацией
Пример
@Test
void shouldSendHeaders() {
webTestClient.get()
.uri("/api/protected")
.header("Authorization", "Bearer jwt-token-here")
.exchange()
.expectStatus().isOk()
.expectHeader().contentType(MediaType.APPLICATION_JSON)
.expectHeader().exists("X-Custom-Header");
}
На собеседовании: интервьюер хочет услышать, что
WebTestClientработает и с MVC, и с WebFlux, в отличие отMockMvc(только MVC) иTestRestTemplate(только реальный сервер). Частая ошибка — думать, чтоWebTestClientтолько для реактивных приложений.