我目前正在为我的 REST 端点编写一些基本的单元测试。我为此使用Mockito。这里有一个例子:
@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()));
}
此实现会导致以下错误:
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
当我将 Mockito 语句中的参数与 Mockito.any()
交换时
Mockito.when(this.service.getItems(Mockito.any())).thenReturn(result);
测试成功运行。这意味着由于某种原因,我放入Mockito
语句中的params
不等于我放入BodyInserters.fromPublisher(params, ItemParams.class)
的params
对象
那么我应该如何测试我的功能呢?
编辑
REST-端点
@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);
}
实际对象@RequestBody Mono<ItemParams> itemParms
与您在测试中创建并通过的对象不同吗?
您可以利用thenAnswer
来验证实际传递给服务的对象的内容:
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;
}
});