我正在使用Spring Reactor Core 3.0.6,我有一个返回Flux的方法:
public Flux<Foo> createFlux(){
return Flux.<List<Foo>,String>generate(/* generator omitted for clarity's sake */ )
.take(Duration.ofSeconds(10)
.flatMap(Flux::fromIterable);
}
生成器函数调用分页的REST api来获取结果,如果API继续返回数据,我希望Flux只运行10秒。
它工作正常,但我想创建一些单元测试,我在创建测试时遇到问题,以验证Flux最多只运行10秒。
我模拟了其余的服务,以便它总是返回数据并写下来:
StepVerifier.withVirtualTime(() -> createFlux())
.thenAwait(Duration.ofSeconds(10))
.verifyComplete();
但它失败了:
java.lang.AssertionError: expectation "expectComplete" failed (expected: onComplete(); actual: onNext([my toString() Foo bean]))
我想我应该以某种方式使用生成的项目,但我无法找到正确的StepVerifier方法。
修改
我尝试使用thenConsumeWhile
跳过所有项目:
StepVerifier.withVirtualTime(() -> createFlux())
.thenAwait(Duration.ofSeconds(10))
.thenConsumeWhile(t -> true)
.verifyComplete();
但现在测试只是无限期地运行而且永远不会结束。
答案 0 :(得分:2)
如果你错过了它,reference guide可能会让你走上正确的道路?
除了最常见的expectNext
,您必须为序列中的每个项目重复这些内容,如果您知道元素的数量或expectNextCount
要跳过元素,则可以使用thenConsumeWhile
基于谓词,
答案 1 :(得分:2)
生成器实际上可能非常重要...... StepVerifier
受限于无限序列,在使用虚拟时间时更是如此。问题是生成器和thenAwait
都在主线程中运行,因此生成器无限制会阻止步进器提前时间,从而阻止序列超时。
由于你想测试take
的持续时间,我不认为虚拟时间是对的(你正在测试模拟时间)。我将使用持续时间使createFlux方法可参数化,并在更短的时间内执行StepVerifier.create()
。
如果你真的想使用某种形式的虚拟时间,我发现让它工作的最低要求是
Scheduler
,在非虚拟线程上隔离生成器循环,然后在StepVerifier的subscribeOn(scheduler)
中使用Supplier
。 .expectNextCount(1)
,确保所有订阅都已订阅并且数据开始流动,然后再尝试推进时间。像这样:
public Flux<Integer> createFlux() {
return Flux.<List<Integer>>generate(sink -> {
sink.next(Arrays.asList(1, 2, 3));
})
.take(Duration.ofSeconds(10))
.flatMap(Flux::fromIterable);
}
@Test
public void so44657525() throws InterruptedException {
Scheduler scheduler = Schedulers.newSingle("test");
AtomicInteger adder = new AtomicInteger();
StepVerifier.withVirtualTime(() -> createFlux()
.subscribeOn(scheduler)
.doOnNext(v -> adder.incrementAndGet())
)
.expectNextCount(1)
.thenAwait(Duration.ofSeconds(10))
.thenConsumeWhile(t -> true)
.verifyComplete();
System.out.println("Total number of values in generated lists: " + adder.get());
}
将expectNextCount(1)
修改为expectNextCount(100_000)
,我有一个打印Total number of values in generated lists: 102405
且耗时40毫秒的游戏。