Reactor StepVerifier测试失败,并带有blockFirst()

时间:2019-01-08 22:11:38

标签: project-reactor

这里是检查数据库中重复名称的代码

public Mono<Void> validateDuplicateName(String name) throws RuntimeException {
    Flux<Customer> customerFlux = customerRepository.findByNameIgnoreCase(name);

    customerFlux.take(1).flatMap( customer -> {
        return Mono.error( new RuntimeException ("ABC99") );
    }).blockFirst();

    return Mono.empty();
}

下面是用于测试 validateDuplicateName 方法的测试脚本

when(customerRepositoryMocked.findByNameIgnoreCase(Mockito.anyString())).thenReturn(Flux.just(customerMocked));
StepVerifier.create(customerValidator.validateDuplicateName(Mockito.anyString()))
        .expectErrorMatches( exception -> exception instanceof RuntimeException )
        .verify();

但是测试失败并显示以下错误

java.lang.RuntimeException: ABC99
..
..
Suppressed: java.lang.Exception: #block terminated with an error
        at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:93)
        at reactor.core.publisher.Flux.blockFirst(Flux.java:2013)
        ... 34 more

我可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

您的StepVerifier实际上只能测试该方法系统返回的Mono.empty()。同时,您使用blockFirst,它将引发发布者发出的任何异常,从而缩短整个断言。

记住StepVerifier可让您断言序列将异步发出的期望值(包括错误,以onError信号的形式)。如果甚至由于创建序列(validateDuplicateName的方法引发而无法创建序列,那么StepVerifier就是无奈的。

但是真正的问题是为什么您会阻止在具有Mono返回类型并且方便使用Mono源的完美方法中使用?您的返回{ {1}}必须从该Mono派生。

您可以使用customerFlux切换到then():这会忽略源元素,但会正确传播错误。