During unit testing retry the response of the mock seems cached, or most probably I am doing something wrong.
I am trying to request something, if error happened then retry twice with delay of 1 second.
public Mono<Object> someMethod(String someParam) {
return someInjectedService.doSomething(someParam)
.doOnError(ex -> System.out.println(ex + ": " + System.currentTimeMillis()))
.retryWhen(Retry.fixedDelay(2, Duration.ofSeconds(1)).filter(ex -> ex instanceof SomeCustomException))
.doOnSuccess(result -> doSomethingOnSuccess(result));
}
My test:
@Test
void testshouldRequestThrice_whenErrorOccurs() {
// Given
String someParam = "testParam";
when(someInjectedService.doSomething(someParam))
.thenReturn(Mono.error(new SomeCustomException("SomeCustomException"))) // 1st response
.thenReturn(Mono.error(new SomeCustomException("SomeCustomException"))) // 2nd response
.thenReturn(Mono.just("SomeValidResponse")); // 3rd valid response
// When
var result = testService.someMethod(someParam).block();
// Then
// Initial request, followed by two retries
verify(someInjectedService, times(3)).doSomething(someParam);
}
here someInjectedService
is a mock.
My plan was to return an exception twice, and on third request return valid response. But what I get is:
org.mockito.exceptions.verification.TooFewActualInvocations: someInjectedService.doSomething("testParam");
Wanted 3 times: -> at shouldRequestThrice_whenErrorOccurs(test.java:138)
But was 1 time:
While I do see 3 prints from .doOnError(ex -> System.out.println(ex + ": " + System.currentTimeMillis()))
block, I feel like the actual request is sent only once.
Thank you in advance,
someInjectedService.doSomething(...)
will indeed technically be called only once.
You could use Mono.defer(() -> someInjectedService.doSomething(someParam))
instead, to ensure the method is effectively called again, which should make your test pass.