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