无法模拟WebClient,在不模拟的情况下调用外部API



我有一个服务,它调用外部API并映射到实体列表中(这是另一个实体(。为了创建单元测试用例,我创建了一个带有所需输出的json文件,并将其映射到那里。

该服务最初使用RestTemplate,我可以用相同的代码轻松地模仿它,但后来我不得不将其更改为WebClient以使其同步,但现在它不再嘲笑WebClient,而是导致了外部API。

任何帮助都将不胜感激,我还没有发布完整的代码,因为我在WebClient中面临问题,特别是当我使用RestTemplate 时,同样的单元测试已经通过

我知道MockWebServer会更容易,但如果可能的话,我正在寻找WebClient中的解决方案

EntityService.java

public Mono<List<EntityDTO>> getNumber(String Uri) {
return WebClient.builder()
.baseUrl(Uri)
.build()
.get()
.exchange()
.flatMap(response -> response.bodyToMono(EntityDTO.class))
.flatMapMany(dto -> Flux.fromIterable(dto.getEntityDetails()))
.map(this::getEntityDTO)
.collectList();}

EntityServiceTest.java

@Test
void shouldReturnEntities() throws IOException {
ServiceInstance si = mock(ServiceInstance.class);
String exampleRequest =new String(Files.readAllBytes(Paths.get("entityPath/entitytest.json")));

ClientResponse response = ClientResponse.create(HttpStatus.OK)
.header(HttpHeaders.CONTENT_TYPE,
MediaType.APPLICATION_JSON_VALUE)
.body(exampleRequest)
.build();
Entity entity = Entity.builder().id("1").name("test")).build

when(si.getServiceId()).thenReturn("external-api");
when(discoveryClient.getInstances(anyString())).thenReturn(List.of(si));            
when(webClientBuilder.build().get()).thenReturn(requestHeadersUriSpec);
when(requestHeadersUriSpec.exchange()).thenReturn(Mono.just(response));
when(entityRepository.findById(eq(entity.getId()))).thenReturn(Optional.of(entity));
Flux<EntityDTO> entityNumbers = entityService.getEntityNumbers(entity.getId(),0,1).
StepVerifier.create(entityNumbers).expectNext(entity).verifyComplete();
}

模拟WebClient可能非常棘手且容易出错。即使你可以涵盖一些简单的阳性案例,也很难测试更复杂的场景,比如错误处理、重试。。。

我推荐WireMock,它为测试web客户端提供了一个非常好的API。以下是的一些例子

stubFor(get("/api")
.willReturn(aResponse()
.withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE)
.withStatus(200)
.withBody(...)
)
);

通过提供不同的存根,您可以轻松地测试阳性和阴性场景

stubFor(get("/api")
.willReturn(aResponse()
.withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE)
.withStatus(500)
)
);

或者使用场景测试重试逻辑,甚至使用延迟模拟超时。

相关内容

最新更新