Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring WebFlux, unit testing Mono and Flux

Interested in reactive programming, I played a bit with the Building a Reactive RESTful Web Service guide. And wanted to move forwrad and add some unit tests.

I tried to test my handler (RouterFunction) with plain Junit/Mockito test. But, because it is reactive, the handler returns a Mono<ServerResponse>. So I had to block() it to test the ServerResponse status but was not able to extract his body to test it. While searching the web for a solution, it seems that all the samples are using the WebTestClient.

My question is:

Given that all samples are using WebTestClient to test a reactive REST service and that it is not easier to (unit) test the body of a ServerResponse. Is it a good practice to unit test a RouterFunction or is it better to always do broader tests with the WebTestClient ?

Thanks a lot.

like image 304
gervais.b Avatar asked Aug 13 '18 20:08

gervais.b


People also ask

What is the difference between flux and Mono?

A Flux object represents a reactive sequence of 0.. N items, whereas a Mono object represents a single value or an empty (0..1) result. Most times, you expect exactly one result or no (zero) result, and not a collection that contains possibly multiple results. In such scenarios, it's more convenient to have a Mono.

What is mono and flux in reactive programming Spring?

Project Reactor is the implementation of Reactive Streams specification. Reactor provides two types: Mono: implements Publisher and returns 0 or 1 elements. Flux: implements Publisher and returns N elements.

Which class is most useful for testing spring WebFlux endpoints?

Learn to unit test spring boot webflux controller using @WebFluxTest annotation and WebTestClient which is used to test webflux endpoints with Junit 5.

How do I get value from mono WebFlux?

Blocking way to get value from Mono WebFlux. You can use the block() method to block the current thread indefinitely and wait for Mono to complete. If the Mono completes, then this method either returns the original value or null (Mono is empty). In case of any errors, then the exception is rethrown.


2 Answers

It seems that the best practice is to use the WebTestClient. However this one can be used without a running server;

The spring-test module includes a WebTestClient that can be used to test WebFlux server endpoints with or without a running server.

-- https://docs.spring.io/spring/docs/5.0.0.BUILD-SNAPSHOT/spring-framework-reference/html/web-reactive.html#web-reactive-tests

like image 82
gervais.b Avatar answered Nov 10 '22 23:11

gervais.b


It depends on what exactly you want to test, for regular method you should use StepVerifier in favor of consume the output of you test. However router functions are unique, because, usually return a serverResponse that contains your data on body, so in that case its better use webClient or webTestClient.

like image 32
nekperu15739 Avatar answered Nov 10 '22 22:11

nekperu15739