Reactor重试机制搭配Mockito存根时重试仅调用首次存根问题咨询
问题产生原因
- Reactor 的
retryWhen重试机制的本质是重新订阅上游的Mono/Flux实例,而非重新执行上游发布者的生成逻辑。你的业务代码中fooRepository.deleteAll()仅在cleanUpDbs方法执行时被调用1次,返回一个固定的Mono.error实例,后续所有重试都是反复订阅这个已经生成的报错Mono,永远只会拿到同一个异常。 - Mockito 配置的多轮返回规则仅对方法的多次调用生效,当前场景下
deleteAll()从头到尾仅被调用1次,只会触发第一个thenReturn配置的异常返回,自然会出现重试耗尽的问题,测试无法通过。
修复方案
核心思路是让每次重试都重新触发fooRepository.deleteAll()的调用,只需使用Mono.defer包裹上游逻辑即可:
@Scheduled(...) public void cleanUpDbs() { // 用Mono.defer包裹,每次订阅都会重新执行lambda内的逻辑 Mono.defer(() -> fooRepository.deleteAll()) .retryWhen(Retry.backoff(3, Duration.ofSeconds(2))) .doOnError(log::error) .block(); }
Mono.defer 是延迟发布者,只有每次出现新的订阅时才会执行内部的lambda表达式,重试触发重新订阅时就会重新调用fooRepository.deleteAll(),依次触发Mockito预先配置的多轮存根返回,原有单元测试不需要修改即可验证通过。
内容的提问来源于stack exchange,提问作者Another Dimension
相关产品推荐
相关产品推荐

