I have this code which uses WebClient to call a third party API.
public Mono<JsonNode> callApi(String url) {
return webClient.get()
.uri(url)
.headers(httpHeaders -> httpHeaders.set(Constants.X_API_KEY, apiKey))
.retrieve()
.onStatus(HttpStatus::is5xxServerError,
res -> {
res.bodyToMono(String.class)
.subscribe(e -> log.error(Constants.EXCEPTION_LOG, e));
return Mono.error(new RetryableException("Server error: " + res.rawStatusCode()));
})
.onStatus(HttpStatus::is4xxClientError,
res -> {
res.bodyToMono(String.class)
.subscribe(e -> log.error("Exception occurred in callPartnerApi: No retries {}", e));
return Mono.error(new Exception("Exception occurred calling partner api, no retries " + res.rawStatusCode()));
})
.bodyToMono(JsonNode.class);
}
I am trying to use Mockito to unit test this and so far I have this which is failing:
@Test
void testCallPartnerApi_then5xxException() {
WebClient.RequestHeadersUriSpec requestHeadersUriSpec = mock(WebClient.RequestHeadersUriSpec.class);
WebClient.RequestHeadersSpec requestHeadersSpec = mock(WebClient.RequestHeadersSpec.class);
WebClient.ResponseSpec responseSpec = mock(WebClient.ResponseSpec.class);
when(webClient.get()).thenReturn(requestHeadersUriSpec);
when(requestHeadersUriSpec.uri(anyString())).thenReturn(requestHeadersSpec);
when(requestHeadersSpec.headers(any())).thenReturn(requestHeadersSpec);
when(requestHeadersSpec.retrieve()).then(invocationOnMock -> Mono.error(new RetryableException("Server error: 500")));
when(responseSpec.onStatus(argThat(x -> x.test(HttpStatus.INTERNAL_SERVER_ERROR)), any())).thenAnswer(invocation -> Mono.error(new RetryableException("Server error: 500")));
StepVerifier.create(partnerService.callPartnerApi("/test"))
.expectError()
.verify();
}
The error I get from this test is this:
java.lang.ClassCastException: class reactor.core.publisher.MonoError cannot be cast to class org.springframework.web.reactive.function.client.WebClient$ResponseSpec
Is using a library like WireMock or MockServerTest the only way to test these scenarios?