我们正在使用Project Reactor 按照下面ServiceTest
中的代码异步运行特定操作。要根据下面的ServiceTest
测试此代码,在为异步操作设置Mono时,我们会让Mono将其结果传递给具有doOnNext
的DirectProcessor进行测试可以使用StepVerifier访问,然后执行我们的测试调用和断言。
StepVerifier#assertNext的JavaDoc读取
消费者抛出的任何AssertionErrors都将在验证期间重新抛出。
我们发现当使用立即调度程序(Schedulers.immediate())时,仅是真的,而在使用单个调度程序(Schedulers.single())时则不是。使用单个调度程序时,不会重新抛出AssertionErrors,即测试总是通过。
是否有可能,如果是这样,如何使用单个调度程序并在验证期间根据JavaDoc重新抛出AssertionErrors?
@Service
@RequiredArgsConstructor
public class Service implements WithReactive, WithTestProcessor<Response> {
@Getter
@Setter
private DirectProcessor<Response> processor = DirectProcessor.create();
@Setter
private Scheduler scheduler = Schedulers.single();
public void doAction() {
Mono.fromSupplier(this::doActionAsync)
.doOnNext(processor::onNext)
.subscribeOn(scheduler)
.subscribe();
}
private Response doActionAsync() {
...
}
...
}
public interface WithReactive {
void setScheduler(Scheduler scheduler);
}
public interface WithTestProcessor<T> {
void setProcessor(DirectProcessor<T> processor);
DirectProcessor<T> getProcessor();
}
@RunWith(SpringRunner.class)
@SpringBootTest
public class ServiceTest {
@Inject
private Collection<WithTestProcessor> withTestProcessors;
@Before
public void setTestProcessors() {
withTestProcessors.forEach(withTestProcessor -> withTestProcessor.setProcessor(DirectProcessor.create()));
}
@Inject
private Collection<WithReactive> withReactives;
@Before
public void makeReactiveSynchronous() {
withReactives.forEach(withReactive -> withReactive.setScheduler(Schedulers.immediate()));
}
@Test
private void test() {
StepVerifier.create(service.getProcessor())
.then(service::doAction)
.assertNext(response -> assertThat(logExtractor.getInsertsByTable("assets")).hasSize(1))
.thenCancel()
.verify();
}
}
答案 0 :(得分:1)
这是三个因素的组合:初始then
,订阅与subscribeOn
和thenCancel
的验证同时发生。
一种解决方法是在StepVerifier执行onNext
之前为thenCancel
提供足够的时间,方法是在thenAwait(Duration.ofMillis(10))
之前添加thenCancel
。