Search code examples
javaspring-bootunit-testingjunitmockito

Unit test the .doOnError in Java


I have a piece of code to send a request via WebClient:

public String getResponse(String requestBody){
 ...
    final WebClient.RequestHeadersSpec<?> request =
        client.post().body(BodyInserters.fromValue(requestBody));

    final String resp =
        req.retrieve().bodyToMono(String.class)
            .doOnError(
                WebClientResponseException.class,
                err -> {
                  // do something
                  throw new InvalidRequestException(err.getResponseBodyAsString());
                })
            .block();
 ...
}

From the code, it looks like the InvalidRequestException will be thrown when the WebClientResponseException happens. However, the test throws the WebClientResponseException instead of the InvalidRequestException.

Here's the part of unit test I wrote to cover the .doOnError part. I tried the following:

...
when(webClientMock.post()).thenReturn(requestBodyUriMock);
when(requestBodyUriMock.body(any())).thenReturn(requestHeadersMock);
when(requestHeadersMock.retrieve()).thenReturn(responseMock);
when(responseMock.bodyToMono(String.class)).thenThrow(new WebClientResponseException(400, "Bad Request", null, null, null));

try {
      String result = someServiceSpy.getResponse(requestBody);
} catch (InvalidRequestException e) {
      assertEquals(expectedCode, e.getRawStatusCode());
}

Solution

  • The solution is I need to wrap the exception in Mono.error, and then the doOnError will be triggered.

    when(responseMock.bodyToMono(String.class)).thenReturn(Mono.error(thrownException));