Search code examples
javareactor

Java Reactor StepVerifier.withVirtualTime loop: repeatedly check with "expectNoEvent()", "expectNext()" and "thenAwait()"


I am learning Java 11 reactor. I have seen this example:

    StepVerifier.withVirtualTime(() -> Flux.interval(Duration.ofSeconds(1)).take(3600))
            .expectSubscription()
            .expectNextCount(3600);

This example just checks that with a Flux<Long> which increments 1 after every second till one hour, the final count is 3600.

But, is there any way to check the counter repeatedly after every second?

I know this:

.expectNoEvent(Duration.ofSeconds(1))
.expectNext(0L)
.thenAwait(Duration.ofSeconds(1))

But I have seen no way to repeatedly check this after every second, like:

.expectNoEvent(Duration.ofSeconds(1))
.expectNext(i)
.thenAwait(Duration.ofSeconds(1))

when i increments till 3600. Is there?


PS: I tried to add verifyComplete() at last in a long-running tests and it will never end. Do I have to? Or just ignore it?


Solution

  • You can achieve what you wanted by using expectNextSequence. You have to pass an Iterable and include every element you expect to arrive. See my example below:

    var longRange = LongStream.range(0, 3600)
        .boxed()
        .collect(Collectors.toList());
    
    StepVerifier
        .withVirtualTime(() -> Flux.interval(Duration.ofSeconds(1)).take(3600))
        .expectSubscription()
        .thenAwait(Duration.ofHours(1))
        .expectNextSequence(longRange)
        .expectComplete().verify();
    

    If you don't add verifyComplete() or expectComplete().verify() then the JUnit test won't wait until elements arrive from the flux and just terminate.

    For further reference see the JavaDoc of verify():

    this method will block until the stream has been terminated