I have this request with WebClient
:
webClient
.get()
.uri(uri)
.accept(MediaType.APPLICATION_OCTET_STREAM)
.<Optional<ByteArrayResource>>exchangeToMono(response -> {
if (response.statusCode().equals(HttpStatus.NOT_FOUND)) {
return Mono.just(Optional.empty());
}
return response.bodyToMono(ByteArrayResource.class).map(Optional::of);
})
.block();
How can I test the logic inside exchangeToMono()
?
I'm using Mockito for testing this way:
given(headersSpecHeadOpMock.exchangeToMono()).willReturn(Mono.just(clientResponse))
But the problem here is that this way I'm not testing the HttpStatus.NOT_FOUND
.
CodePudding user response:
The problem I was having is that I was mocking the ClientResponse, but I would have to Mock a Function<ClientResponse, ? extends Mono<Optional<ByteArrayResource>>>
.
The solution was to use an ArgumentCaptor to get the argument and then make the assert of his value like this:
ArgumentCaptor declaration:
ArgumentCaptor<Function<ClientResponse, ? extends Mono<Optional<ByteArrayResource>>>> captorLambda = ArgumentCaptor.forClass(Function.class);
Capture the argument:
given(headersSpecGetOpMock.<Optional<ByteArrayResource>>exchangeToMono(captorLambda.capture())).willReturn(Mono.just(Optional.empty()));
Assert the value returned by the client response:
assertThat(captorLambda.getValue().apply(clientResponse).block()).isEqualTo(Optional.empty());```
CodePudding user response:
Consider rewriting your code as follows:
webClient
.get()
.uri(uri)
.accept(MediaType.APPLICATION_OCTET_STREAM)
.retrive()
.onStatus(status -> HttpStatus.NOT_FOUND == status, response -> Mono.just(Optional.empty()))
.bodyToMono(ByteArrayResource.class);
.map(Optional::of)
.block();
Now you can mock retrieve()
method to test your conditions easily.
As a side note, please consider dropping block()
call, this defeats the purpose of using reactive programming.