Testing support library providing utilities for verifying reactive stream behavior in Project Reactor applications
npx @tessl/cli install tessl/maven-io-projectreactor--reactor-test@3.7.0Reactor Test is a comprehensive testing support library for Project Reactor's reactive streams, providing utilities to verify the behavior of Publishers (Flux and Mono) through declarative APIs. It enables developers to create test scenarios that express expectations about events that occur upon subscription, including data emissions, errors, completion, and timing.
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<version>3.7.6</version>
<scope>test</scope>
</dependency>import reactor.test.StepVerifier;
import reactor.test.publisher.TestPublisher;
import reactor.test.subscriber.TestSubscriber;
import reactor.test.scheduler.VirtualTimeScheduler;
import reactor.test.publisher.PublisherProbe;import reactor.core.publisher.Flux;
import reactor.test.StepVerifier;
import java.time.Duration;
// Basic verification of a simple sequence
StepVerifier.create(Flux.just("foo", "bar"))
.expectNext("foo")
.expectNext("bar")
.expectComplete()
.verify();
// Virtual time testing for delayed sequences
StepVerifier.withVirtualTime(() -> Flux.just("hello").delayElements(Duration.ofMinutes(1)))
.expectSubscription()
.expectNoEvent(Duration.ofMinutes(1))
.expectNext("hello")
.expectComplete()
.verify();Reactor Test provides four main testing approaches:
Additional utilities support virtual time manipulation, race condition testing, and log output verification.
Verify reactive sequences declaratively by expressing expectations about events that will happen upon subscription.
interface StepVerifier {
static <T> FirstStep<T> create(Publisher<? extends T> publisher);
static <T> FirstStep<T> withVirtualTime(Supplier<? extends Publisher<? extends T>> scenarioSupplier);
Duration verify();
Duration verify(Duration duration);
}Create test publishers that can be manually controlled to emit specific signals for testing subscriber behavior.
abstract class TestPublisher<T> implements Publisher<T> {
static <T> TestPublisher<T> create();
static <T> TestPublisher<T> createCold();
TestPublisher<T> next(T value);
TestPublisher<T> error(Throwable t);
TestPublisher<T> complete();
}Instrument publishers to capture subscription events and verify control flow without affecting the actual data flow.
interface PublisherProbe<T> {
static <T> PublisherProbe<T> of(Publisher<? extends T> source);
static <T> PublisherProbe<T> empty();
boolean wasSubscribed();
boolean wasCancelled();
void assertWasSubscribed();
}Create subscribers that collect signals programmatically for complex testing scenarios requiring more flexibility than StepVerifier.
interface TestSubscriber<T> extends CoreSubscriber<T> {
static <T> TestSubscriber<T> create();
static TestSubscriberBuilder builder();
List<T> getReceivedOnNext();
boolean isTerminated();
void block(Duration timeout);
}Manipulate virtual time to test time-based reactive operations without real delays.
class VirtualTimeScheduler implements Scheduler {
static VirtualTimeScheduler create();
static VirtualTimeScheduler getOrSet();
void advanceTimeBy(Duration delayTime);
void advanceTimeTo(Instant instant);
}Additional utilities for advanced testing scenarios including race condition testing and log output verification.
class RaceTestUtils {
static void race(Runnable... rs);
static void race(Scheduler s, Runnable... rs);
}
class TestLogger implements Logger {
TestLogger();
String getOutContent();
String getErrContent();
}// Core configuration options
class StepVerifierOptions {
static StepVerifierOptions create();
StepVerifierOptions initialRequest(long initialRequest);
StepVerifierOptions virtualTimeSchedulerSupplier(Supplier<? extends VirtualTimeScheduler> vtsLookup);
}
// Test publisher violation modes
enum TestPublisher.Violation {
REQUEST_OVERFLOW, // Allow next calls despite insufficient request
ALLOW_NULL, // Allow null values in next calls
CLEANUP_ON_TERMINATE, // Allow multiple termination signals
DEFER_CANCELLATION // Ignore cancellation signals
}
// Fusion requirements for TestSubscriber
enum TestSubscriber.FusionRequirement {
FUSEABLE, // Expect publisher to be fuseable
NOT_FUSEABLE, // Expect publisher to not be fuseable
NONE // No fusion requirements
}