Reputation: 10589
Im currently writing some basic unit tests for my REST-Endpoints. I use Mockito for that. Here one example:
@MockBean
private MyService service;
@Test
public void getItems() {
Flux<Item> result = Flux.create(sink -> {
sink.next(new Item("1"));
sink.next(new Item("2"));
sink.complete();
});
Mono<ItemParams> params = Mono.just(new ItemParams("1"));
Mockito.when(this.service.getItems(params)).thenReturn(result);
this.webClient.post().uri("/items")
.accept(MediaType.APPLICATION_STREAM_JSON)
.contentType(MediaType.APPLICATION_STREAM_JSON)
.body(BodyInserters.fromPublisher(params, ItemParams.class))
.exchange()
.expectStatus().isOk()
.expectBodyList(Item.class).isEqualTo(Objects.requireNonNull(result.collectList().block()));
}
This implementation leads to the following error:
java.lang.AssertionError: Response body expected:<[Item(name=1), Item(name=2)]> but was:<[]>
> POST /items
> WebTestClient-Request-Id: [1]
> Accept: [application/stream+json]
> Content-Type: [application/stream+json]
Content not available yet
< 200 OK
< Content-Type: [application/stream+json;charset=UTF-8]
No content
When I exchange the parameter in the Mockito Statement with Mockito.any()
Mockito.when(this.service.getItems(Mockito.any())).thenReturn(result);
The test runs through successfully.
That means that for some reason the params
I put into the Mockito
Statement isnt equal to the params
object which I put into BodyInserters.fromPublisher(params, ItemParams.class)
How am I supposed to test my functionality then?
EDIT
REST-Endpoint
@PostMapping(path = "/items", consumes = MediaType.APPLICATION_STREAM_JSON_VALUE, produces = MediaType.APPLICATION_STREAM_JSON_VALUE)
public Flux<Item> getItems(@Valid @RequestBody Mono<ItemParams> itemParms) {
return this.service.getItems(itemParms);
}
Upvotes: 8
Views: 32131
Reputation: 26522
Wouldn't the actual object, @RequestBody Mono<ItemParams> itemParms
, be different than the one you create and pass in the test?
You could take advantage of thenAnswer
in order to verify the content of the object that is actually passed to the service:
Mockito.when(this.service.getItems(Mockito.any()))
.thenAnswer(new Answer<Flux<Item>>() {
@Override
public Flux<Item> answer(InvocationOnMock invocation) throws Throwable {
Mono<ItemParams> mono = (Mono<ItemParams>)invocation.getArgument(0);
if(/* verify that paseed mono contains new ItemParams("1")*/){
return result;
}
return null;
}
});
Upvotes: 5