java - 如何使用 JUnit 模拟这个 webClient?
问题描述
我正在尝试模拟以下方法:
public Mono<PResponse> pay(final String oId,final Double amount) {
return webClient
.put()
.uri("/order/{oId}/amount/{amount}",oId,amount)
.body(BodyInserts
.fromObject(PRequest))
.exchange()
.flatMap(
response -> {
if(response.statusCode().is4xxClientError()) {
// call error Function
} else {
return response
.bodyToMono(PResponse.class)
.flatMap(pResponse -> {
return Mono.just(pResposne)
});
}
}
);
}
供您参考,webClient 是一个私有实例。
解决方案
您可以使用MockWebServer。这是一个示例,使用此博客文章中的代码:
服务
class ApiCaller {
private WebClient webClient;
ApiCaller(WebClient webClient) {
this.webClient = webClient;
}
Mono<SimpleResponseDto> callApi() {
return webClient.put()
.uri("/api/resource")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "customAuth")
.syncBody(new SimpleRequestDto())
.retrieve()
.bodyToMono(SimpleResponseDto.class);
}
}
测试
class ApiCallerTest {
private final MockWebServer mockWebServer = new MockWebServer();
private final ApiCaller apiCaller = new ApiCaller(WebClient.create(mockWebServer.url("/").toString()));
@AfterEach
void tearDown() throws IOException {
mockWebServer.shutdown();
}
@Test
void call() throws InterruptedException {
mockWebServer.enqueue(
new MockResponse()
.setResponseCode(200)
.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.setBody("{\"y\": \"value for y\", \"z\": 789}")
);
SimpleResponseDto response = apiCaller.callApi().block();
assertThat(response, is(not(nullValue())));
assertThat(response.getY(), is("value for y"));
assertThat(response.getZ(), is(789));
RecordedRequest recordedRequest = mockWebServer.takeRequest();
//use method provided by MockWebServer to assert the request header
recordedRequest.getHeader("Authorization").equals("customAuth");
DocumentContext context = JsonPath.parse(recordedRequest.getBody().inputStream());
//use JsonPath library to assert the request body
assertThat(context, isJson(allOf(
withJsonPath("$.a", is("value1")),
withJsonPath("$.b", is(123))
)));
}
}
推荐阅读
- html - 在请求标头中传递令牌是一种保护服务的安全方式
- python - Python - subprocess.Popen 一次又一次地打破我的大脑
- python - 如何迭代一个numpy矩阵?
- cmake - 访问当前 c++ 文件范围之外的头文件
- typescript - 在 mikroORM 中创建迁移时数据库不存在
- javascript - 获取两个输入的乘法并使用javascript将其放入另一个输入中
- reactjs - 无法更新状态
- scala - 当使用 scala 路径相关类型作为函数 codomain 时,为什么无法为该函数添加别名?
- kivy - KivyMD:无论如何尝试,小部件文本都不会更新
- html - CSS 图片库页面的边距空间比其他页面少?如何在所有页面上获得干净统一的布局外观?