我有以下的服务方法,即使用spring请求webclient获得响应。
public Mono<String> fetch(String body, HttpHeaders headers, String correlationId) {
Mono<String> response;
try {
response = postRequest(URI, headers, body);
} catch (Exception exception) {
throw new ExceptionHandler(HttpStatus.BAD_REQUEST, ErrorCode.REQUEST_ERROR);
}
return response;
}
private Mono<String> postRequest(String uri, HttpHeaders headers, String body) {
return getStringMono(uri, headers, body).onErrorResume(exception -> {
if (exception instanceof WebClientResponseException.Unauthorized) {
accessTokenCache.invalidate(ACCESS_TOKEN);
String updatedToken = accessTokenCache.getIfPresent(ACCESS_TOKEN);
headers.replace(AUTHORIZATION, Collections.singletonList(updatedToken));
return getStringMono(uri, headers, body);
} else {
log.info(exception.getMessage());
throw new ExceptionHandler(HttpStatus.BAD_REQUEST, ErrorCode.REQUEST_ERROR);
}
});
}
private Mono<String> getStringMono(String uri, HttpHeaders headers, String body) {
return webClient.post().uri(uri).headers(httpHeaders -> httpHeaders.addAll(headers))
.body(Mono.just(body), String.class).retrieve().bodyToMono(String.class);
}
我想使用junit测试上面的代码,并编写了下面的测试用例
@Test
public void testUnauthorizedException() {
RequestBodyUriSpec reqBodyUriMock = mock(WebClient.RequestBodyUriSpec.class);
RequestBodySpec reqBodyMock = mock(WebClient.RequestBodySpec.class);
RequestHeadersSpec reqHeaderMock = mock(WebClient.RequestHeadersSpec.class);
ResponseSpec responseSpec = mock(WebClient.ResponseSpec.class);
when(webClient.post()).thenReturn(reqBodyUriMock);
when(reqBodyUriMock.uri(ArgumentMatchers.<String>notNull())).thenReturn(reqBodyMock);
when(reqBodyMock.headers(any())).thenReturn(requestBodySpec);
when(reqBodyMock.body(any(), eq(String.class))).thenReturn(reqHeaderMock);
when(reqHeaderMock.retrieve()).thenReturn(responseSpec);
ExchangeFunction exchangeFunction = mock(ExchangeFunction.class);
given(exchangeFunction.exchange(any(ClientRequest.class))).willReturn(Mono.error(WebClientResponseException.Unauthorized.create(HttpStatus.UNAUTHORIZED.value(), "Unauthorized", null, null, null)));
when(responseSpec.bodyToMono(ArgumentMatchers.<Class<String>>notNull()))
.thenThrow(WebClientResponseException.Unauthorized.create(HttpStatus.UNAUTHORIZED.value(), "Unauthorized", null, null, null));
ExceptionHandler exception = assertThrows(
ExceptionHandler.class, () -> client.fetch(body, headers, correlationId));
assertEquals(ErrorCode.REQUEST_ERROR, exception.getMessage());
}
测试不是覆盖未授权的异常(如果是块)而是它的出现并进入获取方法的catch块,如何重构测试以覆盖未授权的异常(如果是块)?
发布于 2022-07-17 02:16:11
使用wiremock可以对webclient进行存根,下面是工作测试。
@Rule public WireMockRule wireMockRule = new WireMockRule(wireMockConfig().port(8888));
@Test
public void testUnauthorizedException() {
String response = FileHelper.readFile(DATA + "Response.json");
RequestBodyUriSpec reqBodyUriMock = mock(WebClient.RequestBodyUriSpec.class);
RequestBodySpec reqBodyMock = mock(WebClient.RequestBodySpec.class);
RequestHeadersSpec reqHeaderMock = mock(WebClient.RequestHeadersSpec.class);
ResponseSpec responseSpec = mock(WebClient.ResponseSpec.class);
when(webClient.post()).thenReturn(reqBodyUriMock);
when(reqBodyUriMock.uri(ArgumentMatchers.<String>notNull())).thenReturn(reqBodyMock);
when(reqBodyMock.headers(any())).thenReturn(requestBodySpec);
when(reqBodyMock.body(any(), eq(String.class))).thenReturn(reqHeaderMock);
when(reqHeaderMock.retrieve()).thenReturn(responseSpec);
when(responseSpec.bodyToMono(ArgumentMatchers.<Class<String>>notNull()))
.thenReturn(Mono.error(Unauthorized.create(HttpStatus.UNAUTHORIZED.value(), "Unauthorized", null, null, null)))
.thenReturn(Mono.just(response));
stubFor(post(URI)
.willReturn(unauthorized()
.withStatus(401)
).willReturn(aResponse()
.withStatus(200)
.withBody("true"))
);
StepVerifier.create(client.fetch(body, headers, correlationId))
.expectNextMatches(response -> response.equals(response))
.expectComplete()
.verify();
}
https://stackoverflow.com/questions/72987612
复制相似问题