WebClient ExchangeFilterFunction JUnit

WebClient ExchangeFilterFunction JUnit

如何获得 ClientResponseErrorService.genericClientFilter 的代码覆盖率?

  @PostConstruct
  public void init() throws SSLException {
    SslContext sslContext = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE)
        .build();
    HttpClient httpClient = HttpClient.create().secure(sslContextSpec -> sslContextSpec.sslContext(sslContext));
    ClientHttpConnector restConnector = new ReactorClientHttpConnector(httpClient);
    webClient = WebClient.builder()
        .baseUrl(basePath)
        .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
        .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
        .filter(ClientResponseErrorService.genericClientFilter)
        .clientConnector(restConnector).build();
  }

这是我在内部过滤器函数中使用的 ClientResponseErrorService class。

public static ExchangeFilterFunction genericClientFilterFunction() {
    return ExchangeFilterFunction.ofResponseProcessor(clientResponse -> {
      if (clientResponse.statusCode().isError()) {
        clientResponse.bodyToMono(String.class).flatMap(clientResponseBody -> {
          try {
            log.info("Into error Handler");
            return Mono.error(getException(clientResponse, clientResponseBody));
          } catch (Exception ex) {
            return Mono.error(getException(clientResponse, clientResponseBody));

          }
        });
        return Mono.just(clientResponse);
      } else {
        return Mono.just(clientResponse);
      }
    });

  }

我通过创建 MockWebServer 来尝试这种方式

@Test
public void exchangeFilterFunctionTest() throws Exception {
    server.enqueue(new MockResponse().addHeader("Content-Type", "application/json; charset=utf-8")
    .setBody("{}").throttleBody(10000, 3, TimeUnit.MILLISECONDS).setResponseCode(400));
    server.enqueue(new MockResponse().addHeader("Content-Type", "application/json; charset=utf-8")
    .setBody("{}").throttleBody(10000, 3, TimeUnit.MILLISECONDS).setResponseCode(401));
    WebClient webClient = WebClient.builder()
    .baseUrl("http://localhost:"+server.getPort())
    .filter(ClientResponseErrorService.genericClientFilterFunction())
    .build();
    Mono<String> responseMono = webClient.get()
    .uri("http://localhost:"+server.getPort()+"/api")
    .retrieve()
    .bodyToMono(String.class).retry(1);
    StepVerifier.create(responseMono).expectNextCount(1).verifyComplete();
}

但它给出了异常

expectation "expectNextCount(1)" failed (expected: count = 1; actual: counted = 0; signal: onError(org.springframework.web.reactive.function.client.WebClientResponseException$NotFound: 404 Not Found from GET http://localhost:55633/api))
java.lang.AssertionError: expectation "expectNextCount(1)" failed (expected: count = 1; actual: counted = 0; signal: onError(org.springframework.web.reactive.function.client.WebClientResponseException$NotFound: 404 Not Found from GET http://localhost:55633/api))

它进入 ClientResponseErrorService class 但在这一行失败 clientResponse.bodyToMono(String.class).flatMap(clientResponseBody -> {

这是一个单元测试示例,用于测试状态代码不是错误时的场景。

@Test
void doNothing_whenStatus200() {
    ClientRequest clientRequest = Mockito.mock(ClientRequest.class);
    ExchangeFunction exchangeFunction = Mockito.mock(ExchangeFunction.class);
    ClientResponse clientResponse = mock(ClientResponse.class);

    given(exchangeFunction.exchange(clientRequest)).willReturn(Mono.just(clientResponse));
    given(clientResponse.statusCode()).willReturn(HttpStatus.OK);

    ExchangeFilterFunction underTest = ClientResponseErrorService.genericClientFilterFunction();

    StepVerifier.create(underTest.filter(clientRequest, exchangeFunction))
            .expectNext(clientResponse)
            .verifyComplete();
}