Java 使用步进检验器对通量进行单元测试(持续时间)
我使用的是Spring反应堆堆芯3.0.6,我有一种返回通量的方法:Java 使用步进检验器对通量进行单元测试(持续时间),java,spring,unit-testing,project-reactor,Java,Spring,Unit Testing,Project Reactor,我使用的是Spring反应堆堆芯3.0.6,我有一种返回通量的方法: public Flux<Foo> createFlux(){ return Flux.<List<Foo>,String>generate(/* generator omitted for clarity's sake */ ) .take(Duration.ofSeconds(10) .flatMap(Flux::fromIterable); }
public Flux<Foo> createFlux(){
return Flux.<List<Foo>,String>generate(/* generator omitted for clarity's sake */ )
.take(Duration.ofSeconds(10)
.flatMap(Flux::fromIterable);
}
但它失败了:
java.lang.AssertionError: expectation "expectComplete" failed (expected: onComplete(); actual: onNext([my toString() Foo bean]))
我想我应该以某种方式使用生成的项目,但是我找不到正确的StepVerifier方法来这样做
编辑
我尝试用跳过每一项,然后使用跳过每一项:
StepVerifier.withVirtualTime(() -> createFlux())
.thenAwait(Duration.ofSeconds(10))
.thenConsumeWhile(t -> true)
.verifyComplete();
但是现在,测试只是无限期地运行,永远不会结束。如果您错过了测试,也许测试可以让您走上正确的道路
除了最常见的expectNext
(您必须对序列中的每个项目重复)之外,如果您知道元素的数量或thencumbers,您可以使用expectNextCount
,而要根据谓词跳过元素,生成器实际上可能非常重要StepVerifier
受无限序列的限制,使用虚拟时间时更是如此。问题是生成器和等待
都在主线程中运行,因此生成器是无限的,这会阻止stepverifier提前时间,进而阻止序列超时
因为您想测试的持续时间,所以我认为虚拟时间是不对的(您测试的是模拟时间)。我将使createFlux方法可以用take duration参数化,并在更短的时间内执行StepVerifier.create()
如果你真的想使用某种形式的虚拟时间,我发现让它工作的最低要求是
通过在测试开始时实例化调度程序
,隔离非虚拟线程上的生成器循环,然后在StepVerifier的供应商
中使用订阅(调度程序)
通过先调用.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());
}
public Flux createFlux(){
返回通量。生成(汇->{
sink.next(Arrays.asList(1,2,3));
})
.take(持续时间秒(10))
.flatMap(通量::fromIterable);
}
@试验
public void so44657525()引发InterruptedException{
Scheduler=Schedulers.newSingle(“测试”);
AtomicInteger加法器=新的AtomicInteger();
带有虚拟时间(()->createFlux()的步骤验证程序
.subscribeOn(调度程序)
.doOnNext(v->adder.incrementAndGet())
)
.expectNextCount(1)
.然后等待(持续时间秒(10))
.ThenConsumerwhile(t->true)
.verifyComplete();
System.out.println(“生成列表中的值总数:“+adder.get()”);
}
将expectNextCount(1)
修改为expectNextCount(100_000)
,我运行了一次,打印了生成列表中的值总数:102405
,耗时40ms。我在3.0.6或3.0.7中找不到consumernextwhile
;因为我不想对序列进行断言,所以我在之后加了一个。然后在之后加上consumerwhile(t->true)
,然后等待,跳过每个元素,只检查持续时间,但测试运行不确定,确实有效。我只做了一个更改:我使用.expectComplete().verifyComplete()来代替.verifyComplete()
。这样,如果通量运行超过10秒,它将抛出断言错误。使用verifyComplete,它将无限期运行。如果通量运行预期的10秒,两种解决方案都可以。
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());
}