【发布时间】:2026-01-13 18:05:01
【问题描述】:
最近我尝试通过设置模拟依赖项以在最后返回成功的 mono.just() 之前返回多个 Mono.error() 来测试单元测试中的重试行为:
@Mock
Dependency dependency;
@InjectMocks
ClassUnderTest classUnderTest;
@Test
void someTest() {
final Object object = new Object();
when(dependency.method(anyString()))
.thenReturn(Mono.error(new Exception()))
.thenReturn(Mono.error(new Exception()))
.thenReturn(Mono.error(new Exception()))
.thenReturn(Mono.just(object));
StepVerifier.create(classUnderTest.method("abc"))
.expectNext(object)
.verifyComplete();
verify(dependency, times(4)).method("abc");
}
上面的设置不起作用,正如我后来发现的那样,Reactor 中的重试不是通过在特定时间内调用方法来完成的,而是通过调用一次方法,获取发布者并重新订阅它一次又一次。
class ClassUnderTest {
private Dependency dependency;
public Mono<Object> method(final String str) {
return this.dependency.method(str).retryWhen(Retry.max(3));
}
}
如果Dependency#method 实现为:
class Dependency {
private OtherDependency otherDependency;
public Mono<Object> method(final String str) {
return this.otherDependency.get(str).map(/* some mapping logic */);
}
}
Dependency#method 不能对OtherDependency#get 是否被延迟做太多假设。因此,Dependency 需要:
class Dependency {
private OtherDependency otherDependency;
public Mono<Object> method(final String str) {
return Mono.defer(() -> this.otherDependency.get(str)).map(/* some mapping logic */);
}
}
既然我们想说每个方法都应该是“可重试的”,这是否意味着我们需要始终使用defer(...)?
还是我误解了什么?
【问题讨论】:
标签: java reactive-programming project-reactor