Project Reactor với các đối tượng Mono và Flux có thể sẽ làm cho các bạn cảm thấy khó khăn khi suy nghĩ về làm sao để viết Unit Test cho các đoạn code reactive. Thật ra thì điều này sẽ giải quyết dễ dàng nếu các bạn sử dụng class StepVerifier của thư viện reactor-test. Cụ thể như thế nào? Trong bài viết này, mình sẽ hướng dẫn các bạn cách viết Unit Test cho Project Reactor sử dụng class StepVerifier các bạn nhé!
Đầu tiên, mình sẽ tạo một Maven project để làm ví dụ:
với reactor-test dependency được khai báo như sau:
1 2 3 4 5 6 7 8 9 10 11 |
<dependency> <groupId>io.projectreactor</groupId> <artifactId>reactor-core</artifactId> <version>3.5.7</version> </dependency> <dependency> <groupId>io.projectreactor</groupId> <artifactId>reactor-test</artifactId> <version>3.5.7</version> <scope>test</scope> </dependency> |
Tất nhiên, chúng ta cũng cần khai báo thêm các dependencies để viết Unit Test nữa:
1 2 3 4 5 6 7 8 9 10 11 12 |
<dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <version>5.9.3</version> <scope>test</scope> </dependency> <dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> <version>3.24.2</version> <scope>test</scope> </dependency> |
Để viết Unit Test cho reactive code, chúng ta sẽ sử dụng class StepVerifier để subscribe vào producer và sau đó thì sử dụng các phương thức được hỗ trợ bởi class StepVerifier để assert kết quả mong muốn trong subscription.
Giả sử bây giờ mình có một phương thức trả về đối tượng Mono đơn giản như sau:
1 2 3 |
public Mono<String> getStudentName() { return Mono.just("Khanh"); } |
Mình sẽ viết code Unit Test cho class này sử dụng class StepVerifier như sau:
1 2 3 4 5 6 7 8 |
@Test public void testGetStudentName() { Demo demo = new Demo(); StepVerifier.create(demo.getStudentName()) .expectNext("Khanh") .verifyComplete(); } |
Như các bạn thấy, chúng ta sẽ sử dụng phương thức create() của class StepVerifier để subscribe vào producer. Đối với Mono object, bởi vì nó chỉ chứa có 1 phần tử nên thông thường chúng ta sẽ sử dụng phương thức expectNext() để lấy phần tử này ra và assert giá trị của nó.
Một điểm các bạn cần lưu ý là sau khi add assertion xong thì các bạn cần gọi phương thức verifyComplete() để unsubscribe producer các bạn nhé!
Flux object cũng tương tự các bạn nhé! Ví dụ mình có method như sau:
1 2 3 |
public Flux<String> getStudentNames() { return Flux.just("Khanh", "Quan"); } |
Test method cho phương thức trên sẽ như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@Test public void testGetStudentNames() { Demo demo = new Demo(); StepVerifier.create(demo.getStudentNames()) .recordWith(ArrayList::new) .expectNextCount(2) .consumeRecordedWith(r -> { assertThat(r) .contains("Khanh", "Quan"); }) .verifyComplete(); } |
Kết quả sau khi chạy test các phương thức trên sẽ như sau: