Mono.elapse 不适用于 StepVerifier?
Mono.elapse does not work with StepVerifier?
根据其 Javadoc,Mono.elapse()
将生成 Mono<Tuple2<Long, T>>
,其中第一个值是订阅和第一个下一个信号之间经过的时间。
以下测试无效
StepVerifier.withVirtualTime(() -> Mono.just(1)
.delaySubscription(Duration.ofSeconds(1))
.elapsed(),
() -> VirtualTimeScheduler.enable(true), 1)
.thenAwait(Duration.ofSeconds(1))
.expectNextMatches(tuple2 -> tuple2.getT1() >= 1000 && tuple2.getT2() == 1)
.verifyComplete();
会抛出异常:
java.lang.AssertionError: expectation "expectNextMatches" failed (predicate failed on value: 11,1)
我原以为流逝的时间至少是1000ms,但结果只有11ms。
我在这里有什么遗漏吗?
elapsed()
运算符确实使用底层 TimedScheduler
来获取时钟 'instants' 以计算时间增量,因此当使用 withVirtualTime
时,底层调度程序应该是 VirtualTimeScheduler
...
但是有一个错误:当使用默认值 Scheduler
时,此类运算符实际上获得了一个缓存在包装器中的公共实例。问题是包装器没有委托其 now
方法,这是 elapsed
.
使用的方法
由于 now()
的默认实现是使用 System.currentTimeMillis()
,您有效地看到的是经过的绕过虚拟时间并报告实时增量。
为了解决这个问题,在错误修复之前,您可以显式创建并提供一个 VirtualTimeScheduler
,如下所示:
@Test
public void elapsedWithVirtualTimeWorkaround() {
//we have to create a reference that will be used in 2 places
VirtualTimeScheduler vts = VirtualTimeScheduler.create();
StepVerifier.withVirtualTime(() -> Mono.just(1)
.delaySubscription(Duration.ofSeconds(1))
.elapsed(vts), //this avoids the cache problem
() -> vts, //the supplied scheduler here will be automatically activated by StepVerifier
1)
.thenAwait(Duration.ofSeconds(1)) //this uses the same vts once again
.expectNextMatches(tuple2 -> tuple2.getT1() >= 1000 && tuple2.getT2() == 1)
.verifyComplete();
}
根据其 Javadoc,Mono.elapse()
将生成 Mono<Tuple2<Long, T>>
,其中第一个值是订阅和第一个下一个信号之间经过的时间。
以下测试无效
StepVerifier.withVirtualTime(() -> Mono.just(1)
.delaySubscription(Duration.ofSeconds(1))
.elapsed(),
() -> VirtualTimeScheduler.enable(true), 1)
.thenAwait(Duration.ofSeconds(1))
.expectNextMatches(tuple2 -> tuple2.getT1() >= 1000 && tuple2.getT2() == 1)
.verifyComplete();
会抛出异常:
java.lang.AssertionError: expectation "expectNextMatches" failed (predicate failed on value: 11,1)
我原以为流逝的时间至少是1000ms,但结果只有11ms。
我在这里有什么遗漏吗?
elapsed()
运算符确实使用底层 TimedScheduler
来获取时钟 'instants' 以计算时间增量,因此当使用 withVirtualTime
时,底层调度程序应该是 VirtualTimeScheduler
...
但是有一个错误:当使用默认值 Scheduler
时,此类运算符实际上获得了一个缓存在包装器中的公共实例。问题是包装器没有委托其 now
方法,这是 elapsed
.
由于 now()
的默认实现是使用 System.currentTimeMillis()
,您有效地看到的是经过的绕过虚拟时间并报告实时增量。
为了解决这个问题,在错误修复之前,您可以显式创建并提供一个 VirtualTimeScheduler
,如下所示:
@Test
public void elapsedWithVirtualTimeWorkaround() {
//we have to create a reference that will be used in 2 places
VirtualTimeScheduler vts = VirtualTimeScheduler.create();
StepVerifier.withVirtualTime(() -> Mono.just(1)
.delaySubscription(Duration.ofSeconds(1))
.elapsed(vts), //this avoids the cache problem
() -> vts, //the supplied scheduler here will be automatically activated by StepVerifier
1)
.thenAwait(Duration.ofSeconds(1)) //this uses the same vts once again
.expectNextMatches(tuple2 -> tuple2.getT1() >= 1000 && tuple2.getT2() == 1)
.verifyComplete();
}