Project Reactor with Mono and Flux objects may make it difficult for you to think about how to write Unit Test for reactive code. Actually, this will be solved easily if you use the StepVerifier class of the reactor-test library. How is it in details? In this tutorial, I will show you how to write Unit Test for Project Reactor using the StepVerifier class!
First, I will create a Maven project as an example:
with reactor-test dependency is declared as follows:
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> |
Of course, we also need to declare additional dependencies to write Unit Test:
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> |
To write Unit Test for reactive code, we will use the StepVerifier class to subscribe to the producer and then use the methods supported by the StepVerifier class to assert the desired results in the subscription.
Suppose now I have a simple method of returning Mono object as follows:
1 2 3 |
public Mono<String> getStudentName() { return Mono.just("Khanh"); } |
I will write a Unit Test code for this class using the StepVerifier class as follows:
1 2 3 4 5 6 7 8 |
@Test public void testGetStudentName() { Demo demo = new Demo(); StepVerifier.create(demo.getStudentName()) .expectNext("Khanh") .verifyComplete(); } |
As you can see, we will use the create() method of the StepVerifier class to subscribe to the producer. For the Mono object, because it contains only one element, normally we will use the expectNext() method to get this element and assert its value.
One point you should note is that after adding the assertions have completed, you need to call the verifyComplete() method to unsubscribe the producers!
The Flux object is similar! For example, I have the following method:
1 2 3 |
public Flux<String> getStudentNames() { return Flux.just("Khanh", "Quan"); } |
The test method for the above method will be as follows:
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(); } |
The result after running the above test methods will be as follows: