我的服务器通过WebClient发送一个请求,代码如下:
public String getResponse(String requestBody){
...
WebClient.RequestHeadersSpec<?> request =
client.post().body(BodyInserters.fromValue(requestBody));
String resp =
request.retrieve().bodyToMono(String.class)
.doOnError(
WebClientResponseException.class,
err -> {
// do something
})
.block();
return resp;
}
我为它编写了一个单元测试,并希望模拟WebClient,以便我可以收到预期的响应:
when(webClientMock.post()).thenReturn(requestBodyUriMock);
when(requestBodyUriMock.body(BodyInserters.fromValue(requestBody))).thenReturn(requestHeadersMock);
when(requestHeadersMock.retrieve()).thenReturn(responseMock);
when(responseMock.bodyToMono(String.class)).thenReturn(Mono.just("response"));
String response = someServiceSpy.getResponse(requestBody);
assertEquals(Mono.just("response"), response);
但是,结果不是"response"
,而是一个html文件。我想我在什么地方犯了错误,但我不知道如何修复它。
2条答案
按热度按时间yzxexxkh1#
getResponse
方法中引用的client
似乎没有设置为您在测试中创建的mock(webClientMock
)。如果在
getResponse
方法中创建这个client
对象,我建议使用一个可以模仿的方法来创建它。您可能希望在此处抛出一个注解和/或一个
@VisibleForTesting
注解,以便明确此方法的存在,从而使测试更容易。然后,您可以在
someServiceSpy
中存根此方法:这将确保您的
mockWebClient
在您的测试中用于您的getResponse
方法。此外,似乎您现有的代码需要稍微编辑一下。
应该是
50few1ms2#
我已经找到了直接模拟
WebClient
的解决方案,而不是将构建逻辑放入一个新的方法中来模拟它。我在这里编写了我的解决方案,以防将来其他人需要它:让我把代码示例放在这里:
首先,我们必须模拟
WebClient
的静态方法builder()
。如果不模拟这个方法,mockito就不能编辑这个方法的行为,并且模拟的WebClient
也不会被使用。我从这个StackOverflow问题的答案中发现了这一点;你可以阅读它了解更多的细节。:How to mock Spring WebClient and builder用上面的方法模拟了
builder()
之后,你会得到一个模拟的WebClient
,它类似于:在我的示例代码中,
client
将调用post()
和body()
,因此编写以下代码:我的单元测试一开始就返回了NPE,因为我使用了
而不是
我认为这是因为代码不“认为”
requestBodyUriMock
正在使用BodyInserters.fromValue(requestBody
的一些原因,我还不知道。