0

I want to make a WebFlux reactive call to a legacy SOAP service, using WebClient.

The structure of the code is as follows:

AtomicReference<MyResponse> atomicReference = new AtomicReference<>();

webClient.post()
   .uri(...)
   .contentType(MediaType.XML)
   .body(Mono.just(myRequest, MyRequest.class)
   .retrieve()
   .onStatus(
       HttpStatus::isError,
        clientResponse ->
           clientResponse.bodyToMono(String.class)
           .flatMap(errorResponseBody ->
                      Mono.error(new ResponseStatusException(                                                                
                      clientResponse.statusCode(), errorResponseBody))))
           .bodyToMono(MyResponse.class)
           .doOnSuccess( (MyResponse response) -> {
               atomicReference.set(response);
            })
           .doOnError(ResponseStatusException.class, error -> {
           //handle error
           })
           .subscribe();

What is the best way to mock such a reactive call?

Mocking a call to the non reactive WebServiceTemplate is simple:

when(webServiceTemplate.marshalSendAndReceive(
  ArgumentMatchers.eq("http://..."),
  jaxbElement) // JaxbElement<MyRequest>
  .thenReturn(myResponse);

Because the call is much simpler, and a the response is returned directly, it is straightforward to mock.

But to mock every stage in the WebClient reactive chain would be tedious, brittle and error prone.

The problem is made more complex because - unless there is a simpler solution - the result is not returned from webClient, but rather passed to doOnSuccess, which is deep in the chain. A WebClient.get() call which returned a Mono directly would be relatively simple to mock.

For the same reason, am unclear how MockWebServer would work here, because it is necessary to verify what is passed to doOnSuccess, not what the return value is.

Is there a straightforward solution?

Thanks

user1052610
  • 4,440
  • 13
  • 50
  • 101

0 Answers0