如何为ClientResponseErrorService.genericClientFilter编写JUnit测试获取覆盖率
问题根因及修复方案
1. 过滤器代码存在逻辑错误
你当前的过滤器实现中,错误状态分支的响应处理流没有被正确返回,导致clientResponse.bodyToMono创建的冷流没有被订阅执行,且原错误响应直接透传给了WebClient默认的错误处理器,抛出了内置的WebClientResponseException,这是你代码执行到对应行未生效的核心原因。
原错误代码片段:
if (clientResponse.statusCode().isError()) { // 此处创建的Mono没有被返回,不会被订阅执行 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)); } }); // 直接返回了原响应,走WebClient默认错误处理逻辑 return Mono.just(clientResponse); }
修正后的过滤器代码:
public static ExchangeFilterFunction genericClientFilterFunction() { return ExchangeFilterFunction.ofResponseProcessor(clientResponse -> { if (clientResponse.statusCode().isError()) { // 直接返回处理后的错误流,让订阅者触发执行 return 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)); } }); } else { return Mono.just(clientResponse); } }); }
2. 测试代码逻辑不符合预期
你当前测试的是错误响应场景,请求返回400、401都是错误码,整个流最终会抛出异常,不会正常返回响应体,所以expectNextCount(1)的断言本身就不成立。同时你加了retry(1)会触发两次请求,如果MockWebServer队列中响应数量不匹配会返回404错误。
修正后的单场景测试代码示例:
@Test public void exchangeFilterFunctionTest_400Error() throws Exception { // 入队单个400错误响应 server.enqueue(new MockResponse() .addHeader("Content-Type", "application/json; charset=utf-8") .setBody("{}") .setResponseCode(400)); WebClient webClient = WebClient.builder() .baseUrl("http://localhost:" + server.getPort()) .filter(ClientResponseErrorService.genericClientFilterFunction()) .build(); Mono<String> responseMono = webClient.get() .uri("/api") .retrieve() .bodyToMono(String.class); // 断言抛出你自定义的异常类型,替换成你getException方法返回的实际异常类 StepVerifier.create(responseMono) .expectError(YourCustomException.class) .verify(); }
如果需要测试重试逻辑,也可以对应调整断言,验证两次请求后抛出预期异常即可。
内容的提问来源于stack exchange,提问作者Harsh Kanakhara
相关产品推荐
相关产品推荐

