How to write a unit test which tests Mono error?

Viewed 2865

I am new to Spring Webflux and I want to know what is the best way to write a unit test to check if an error is being thrown:

public Mono<String> update(UpdateModel updateModel) {
        return webClient.post()
                .uri(updatePath)
                .bodyValue(updateModel)
                .retrieve()
                .onStatus(httpStatus -> !HttpStatus.OK.equals(httpStatus),
                        clientResponse -> Mono.error(new ServerSideException("Failed to update")))
                .bodyToMono(String.class);
    }

What is the best way to write a unit test ?

This is what I am using:

@Test
public void shouldThrowServerErrorIfUpdateServiceCallFails() {
    when(responseSpecMock.onStatus(any(), any())).thenReturn(responseSpecMock);
    when(responseSpecMock.bodyToMono(String.class)).thenReturn(Mono.error(new ServerSideException("Failed to update")));

    var response = client.update(updateModel);

    StepVerifier.create(response)
            .expectError(ServerSideException.class)
            .verify();
}

The error is actually thrown from the lambda, not being thrown from bodyToMono call.

This is obviously not correct, but I don't know any better way to check it via unit test.

1 Answers

In my opinion, the best way to test how WebFlux behaves in both normal and error scenarios is to set up a test web server with Wiremock or Mountebank and avoid mocking completely. This way you are assured that your tests are exercising the WebFlux code in the same way as in real life.

Mocking and stubbing is very useful when used appropriately, but they are usually a waste of time when testing 3rd party libraries such as WebFlux. Shameless plug: I wrote an article to explain this point in more detail.

Related