I have a simple implementation of WebClient request:
public Mono<Todo> getTodoWithSimpleRetry(String id) {
RetryBackoffSpec retrySpec = Retry.fixedDelay(3, Duration.ofSeconds(2))
.doBeforeRetry(beforeRetry -> {
log.info("Attempt to retry: " + (beforeRetry.totalRetries() + 1));
}).doAfterRetry(afterRetry -> {
log.error("After retry {}", afterRetry.failure().getMessage());
})
.onRetryExhaustedThrow(((retrySpec1, retrySignal) -> {
throw new TodoServiceException("Max retry exceeded. Todo Service is not available", HttpStatus.SERVICE_UNAVAILABLE.value());
}));
return webClient.get()
.uri("/todo/{id}", id)
.retrieve()
.bodyToMono(Todo.class)
.retryWhen(retrySpec)
;
}
and I'm trying to test that exception TodoServiceException will be thrown after all retry attempts but I don't want to wait time between all retries. I found that it could be done through StepVerifier.withVirtualTime. And my example below:
@Test
void testRetry() {
mockBackEnd.enqueue(new MockResponse().setResponseCode(500));
mockBackEnd.enqueue(new MockResponse().setResponseCode(500));
mockBackEnd.enqueue(new MockResponse().setResponseCode(500));
mockBackEnd.enqueue(new MockResponse().setResponseCode(500));
StepVerifier.withVirtualTime(() -> todoWebClient.getTodoWithSimpleRetry("1"))
.expectSubscription()
.thenAwait(Duration.ofSeconds(2))
.thenAwait(Duration.ofSeconds(2))
.thenAwait(Duration.ofSeconds(2))
.expectError(TodoServiceException.class)
.verify();
}
But the problem is that test always stuck on the second retry and nothing happens.