如何对 Flux 输出进行与顺序无关的断言?

How to make order-independent assertions on Flux output?

我有一个test case for a Flux from Project Reactor大致是这样的:

testMultipleChunks(StepVerifier.FirstStep<Chunk> verifier, Chunk chunk1, Chunk chunk2) {
    verifier.then(() -> {
        worker.add(chunk1);
        worker.add(chunk2);
        worker.update();
    })
    .expectNext(chunk1, chunk2)
    .verifyTimeout(Duration.ofSeconds(5));
}

事实是,我的工作人员被鼓励并行化工作,这意味着输出的顺序是未定义的。 chunk2, chunk1 同样有效。

如何以与顺序无关的方式对输出进行断言?

我关心的属性:

我试过这个:

testMultipleChunks(StepVerifier.FirstStep<Chunk> verifier, Chunk chunk1, Chunk chunk2) {
    Set<Chunk> expectedOutput = Set.of(chunk1, chunk2);
    verifier.then(() -> {
        worker.add(chunk1);
        worker.add(chunk2);
        worker.update();
    })
   .recordWith(HashSet::new)
   .expectNextCount(expectedOutput.size())
   .expectRecordedMatches(expectedOutput::equals)
   .verifyTimeout(Duration.ofSeconds(5));
}

虽然我认为这做出了我想要的断言,但它在可读性方面出现了可怕的下降。一个清晰的一行、一种方法的断言被 行和大量额外的标点符号所取代。

expectedRecordedMatches 在失败时也非常没有信息,只说“预期的集合谓词匹配”而没有提供任何关于期望是什么或结果有多接近的信息。

写这个测试的更清晰的方法是什么?

StepVerifier 不太适合它,因为它会在每个信号发出时验证它,并根据设计实现异步信号的预期顺序。

这特别棘手,因为(看起来)您的测试发布商没有明确完成。

如果它在 N 个元素之后完成(N 是此处的预期数量),我会将传递给 StepVerifier.create 的发布者从 flux 更改为 flux.collectList()。这样,您将获得 onNextList 视图,并且您可以根据需要声明列表(例如,使用我推荐的 AssertJ)。

最近版本的 Reactor 中的一个替代方案是 TestSubscriber,它可用于驱动 requestcancel() 而无需对阻塞或何时执行断言有任何特别的意见.相反,它在内部存储它看到的事件(onNext 进入 ListonCompleteonError 存储为终端 Signal...)和您可以访问这些以进行任意断言。