Skip to content

12.3.3 Kiểm thử với máy chủ thực

Các bài kiểm thử bạn đã viết cho đến nay đều dựa vào một cách triển khai giả (mock) của Spring WebFlux, do đó không cần một máy chủ thực. Nhưng đôi khi bạn có thể cần kiểm thử một controller WebFlux trong ngữ cảnh của một máy chủ như Netty hoặc Tomcat, và có thể có cả repository hoặc các dependency khác. Nói cách khác, bạn có thể muốn viết một bài kiểm thử tích hợp (integration test).

Để viết một bài kiểm thử tích hợp sử dụng WebTestClient, bạn bắt đầu bằng cách chú thích lớp kiểm thử với @RunWith@SpringBootTest, giống như bất kỳ bài kiểm thử tích hợp nào của Spring Boot, như thể hiện dưới đây:

java
package tacos;

import java.io.IOException;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.reactive.server.WebTestClient;

@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
public class TacoControllerWebTest {

  @Autowired
  private WebTestClient testClient;

}

Bằng cách thiết lập thuộc tính webEnvironmentWebEnvironment.RANDOM_PORT, bạn đang yêu cầu Spring khởi động một máy chủ thực đang chạy và lắng nghe trên một cổng được chọn ngẫu nhiên.

Bạn sẽ nhận thấy rằng bạn cũng đã tự động gán (@Autowired) một WebTestClient vào lớp kiểm thử. Điều này không chỉ có nghĩa là bạn sẽ không còn phải tạo một WebTestClient trong các phương thức kiểm thử nữa, mà còn có nghĩa là bạn cũng không cần chỉ rõ một URL đầy đủ khi thực hiện các yêu cầu. Đó là vì WebTestClient sẽ được cấu hình để biết cổng mà máy chủ kiểm thử đang chạy. Giờ đây, bạn có thể viết lại shouldReturnRecentTacos() thành một bài kiểm thử tích hợp sử dụng WebTestClient được tự động gán như sau:

java
@Test
public void shouldReturnRecentTacos() throws IOException {
  testClient.get().uri("/api/tacos?recent")
    .accept(MediaType.APPLICATION_JSON).exchange()
    .expectStatus().isOk()
    .expectBody()
      .jsonPath("$").isArray()
      .jsonPath("$.length()").isEqualTo(3)
      .jsonPath("$[?(@.name == 'Carnivore')]").exists()
      .jsonPath("$[?(@.name == 'Bovine Bounty')]").exists()
      .jsonPath("$[?(@.name == 'Veg-Out')]").exists();
}

Bạn chắc chắn đã nhận thấy rằng phiên bản mới của shouldReturnRecentTacos() này có ít mã nguồn hơn rất nhiều. Bạn không còn cần tạo một WebTestClient nữa vì bạn sẽ sử dụng thể hiện được tự động gán. Và bạn cũng không cần phải giả lập TacoRepository vì Spring sẽ tạo một thể hiện của TacoController và tự động chèn một TacoRepository thực. Trong phiên bản mới của phương thức kiểm thử này, bạn sử dụng biểu thức JSONPath để xác minh các giá trị được trả về từ cơ sở dữ liệu.

WebTestClient rất hữu ích khi, trong quá trình kiểm thử, bạn cần tiêu thụ API được cung cấp bởi một controller WebFlux. Nhưng điều gì xảy ra khi chính ứng dụng của bạn lại là bên tiêu thụ một API khác? Hãy chuyển sự chú ý sang phía client trong câu chuyện web phản ứng của Spring và xem cách WebClient cung cấp một REST client xử lý các kiểu phản ứng như MonoFlux.

Released under the MIT License.