这是检查数据库中重复名称的代码
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
我可以寻求帮助吗?
你的
StepVerifier
实际上只能测试方法系统返回的Mono.empty()
。同时,您使用 blockFirst
,这将引发发布者发出的任何异常,从而使整个断言短路。
记住
StepVerifier
可以让您断言序列将异步发出您期望的内容(包括错误,以 onError
信号的形式)。如果序列甚至无法创建,因为创建它的方法 (validateDuplicateName
) 会抛出异常,那么 StepVerifier
就无能为力了。
但真正的问题是 你到底为什么要阻塞一个具有
Mono
返回类型并且具有完美的 Mono
方便源的方法? 你的返回 Mono
必须源自该 customerFlux
。
您可以使用
then()
切换到 Mono<Void>
:这会忽略源元素,但会正确传播错误。
如果您的 if
. blockFirst()
或 . block()
是不可避免的,并且您可能仍然想让 StepVerifier 在没有 Suppressed: java.lang.Exception: #block terminated with an error
的情况下成功,那么请将 . blockFirst()
或 . block()
替换为 .subscribe()
更改自:
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();
}
更改为:
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") );
}).subscribe();
return Mono.empty();
}
一般来说,当
StepVerifier
失败并出现空 bodyToMono
或 onStatus
--> HttpStatusCode::isError
导致空 bodyToMono
当错误没有设置正文时,.block()
将导致
Suppressed: java.lang.Exception: #block terminated with an error
将
.block()
更改为 .subscribe()
后,我们可以放弃此错误并根据需要验证测试结果。