I'm trying to use Reactor's virtual time feature, but the test blocks indefinitely (without timeout) or throws an AssertionError (with timeout):
@Test
public void test() {
StepVerifier.withVirtualTime(() ->
Flux.just(1, 2, 3, 4).delayElements(Duration.ofSeconds(1)))
.expectSubscription()
.expectNextCount(4)
.expectComplete()
.verify(Duration.ofSeconds(10));
}
The exception is:
java.lang.AssertionError: VerifySubscribertimed out on reactor.core.publisher.FluxConcatMap$ConcatMapImmediate@66d1af89
The same example with real time works as expected:
@Test
public void test2() {
StepVerifier.create(Flux.just(1, 2, 3, 4).delayElements(Duration.ofSeconds(1)))
.expectSubscription()
.expectNextCount(4)
.expectComplete()
.verify(Duration.ofSeconds(10));
}
I can not see an error in my first example following Manipulating Time from the reference.
What is wrong?
You need to use .thenAwait(Duration), otherwise the (virtual) clock won't move, and the delay never happens. You can also use .expectNoEvent(Duration) after the expectSubscription().
For example:
@Test
public void test() {
StepVerifier.withVirtualTime(() ->
Flux.just(1, 2, 3, 4).delayElements(Duration.ofSeconds(1)))
.expectSubscription() //t == 0
//move the clock forward by 1s, and check nothing is emitted in the meantime
.expectNoEvent(Duration.ofSeconds(1))
//so this effectively verifies the first value is delayed by 1s:
.expectNext(1)
//and so on...
.expectNoEvent(Duration.ofSeconds(1))
.expectNext(2)
//or move the clock forward by 2s, allowing events to take place,
//and check last 2 values where delayed
.thenAwait(Duration.ofSeconds(2))
.expectNext(3, 4)
.expectComplete()
//trigger the verification and check that in realtime it ran in under 200ms
.verify(Duration.ofMillis(200));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With