Spring 5 Web Reactive: Flux, Mono, and JUnit Testing

DZone 's Guide to

Spring 5 Web Reactive: Flux, Mono, and JUnit Testing

In this article we discuss how to use Flux, Mono, and JUnit within Spring Webflux to sure up our reactive programs.

· Java Zone ·
Free Resource

The reactive-stack web framework, Spring WebFlux, has been added to Spring 5.0. It is fully non-blocking, supports reactive streams back-pressure, and runs on such servers as Netty, Undertow, and Servlet 3.1+ containers.

Reactive processing is a paradigm that enables developers to build non-blocking, asynchronous applications that can handle back-pressure (flow control). Reactive systems better utilize modern processors. Also, the inclusion of back-pressure in reactive programming ensures better resilience between decoupled components.

Reactive systems have certain characteristics that make them ideal for low-latency, high-throughput workloads. Project Reactor and the Spring portfolio work together to enable developers to build enterprise-grade reactive systems that are responsive, resilient, elastic, and message-driven.

Flux and Mono:

Spring Webflux uses Project Reactor as reactive library. Spring WebFlux heavily uses two publishers:

  • Mono: Returns 0 or 1 element.
  • Flux: Returns 0…N elements.

Reactor is a Reactive Streams library and, therefore, all of its operators support non-blocking back-pressure. Reactor has a strong focus on server-side Java. It is developed in close collaboration with Spring. WebFlux requires Reactor as a core dependency but it is interoperable with other reactive libraries via Reactive Streams.

Create a Maven project with the following dependencies


Create a FluxTest test case using JUnit 5 with various test methods that helps to create and test Flux component.


Flux is a Reactive Stream Publisher with rx operators that emit 0 to N elements and then completes (successfully or with an error).

The just method creates a new flux that emits the provided elements or a single element and then completes. The subscribe method is used to subscribe a Consumer to the Flux that will consume all the elements in the sequence, as well as a Consumer that will handle errors. You can concatenate emissions of this Flux with the provided Publisher using the concatWith method. On invoking the error method, Flux is created that terminates with the specified error immediately after being subscribed to. 

Create FluxTestUsingStepVerifier test case that helps to test Flux component in different ways


A StepVerifier provides a declarative way of creating a verifiable script for an async Publisher sequence by expressing expectations about the events that will happen upon subscription.

The verification must be triggered after the terminal expectations (completion, error, cancellation) has been declared, by calling one of the verify() methods.

StepVerifier can be created around a Publisher using create(Publisher) or withVirtualTime(Supplier<Publisher). Set up individual value expectations using expectNext, expectNextMatches(Predicate), assertNext(Consumer), expectNextCount(long), or expectNextSequence(Iterable)

Trigger subscription actions during the verification using either thenRequest(long) or thenCancel(). Finalize the test scenario using a terminal expectation: expectComplete(),   expectError(), expectError(Class), expectErrorMatches(Predicate), or thenCancel().

Create a test case called MonoTest that helps to create and test the Mono component in different ways


Mono is a Reactive Streams Publisher with basic rx operators that completes successfully by emitting an element, or with an error.

The verifyComplete() method of StepVerifier triggers the verification, expecting a completion signal as terminal event. The expectError(class) method of StepVerifier expects an error of the specified type.

Let's explore some factory methods of Flux/Mono that help to filter, transform, and combine the Publisher stream

Filter the source against the given predicate using filter method. Transform the elements emitted by the Flux using map and flatmap methods. Combine the reactive streams using the following methods

  • concat.
  • merge.
  • zip.

Handle errors in the reactive streams using

  • doOnError.
  • onErrorReturn.

Creating infinite reactive streams using interval method. Create another test case to implement filter method.


Filter evaluates each source value against the given Predicate. If the predicate test succeeds, the value is emitted. If the predicate test fails, the value is ignored and a request of 1 is made upstream.

Create a test case to transform a reactive stream using map 


Create a test case to transform a reactive stream using flatmap:


Create a test case to combine the reactive stream using concat, merge, and zip.


Create a test to handle the errors in reactive stream



Add behavior triggered when the Flux completes with an error matching the given exception type.


Type Parameters: E — the type of the error to handle

Parameters: exceptionType, the type of exceptions to handle, onError, the error handler for each error.

Returns: an observed Flux


Simply emit a captured fallback value when an error is observed on this Flux.


Parameters: fallbackValue, the value to emit if an error occurs

Returns: a new falling back Flux.

flux, java, junit, mono, spring 5, spring webflux, tutorial

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}