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();
}
如何获得 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();
}