【发布时间】:2019-08-02 21:18:51
【问题描述】:
我正在使用 apache http 客户端来使用服务,并且我需要根据超时和响应代码重试请求。 为此,我实现了如下代码。如何为超时和响应代码场景编写重试逻辑的 junit 测试。我想以这样的方式编写单元测试,当我发送任何 post/get 请求时,如果它返回 429 错误代码响应或任何 TimeOutException,我应该确保重试逻辑正确执行。我不知道如何为重试逻辑编写单元测试。 通过谷歌搜索,我找到了以下链接,但它对我没有帮助。
Unit testing DefaultHttpRequestRetryHandler
我正在使用 junit、Mockito 编写单元测试和 PowerMock 来模拟静态方法。
public class GetClient {
private static CloseableHttpClient httpclient;
public static CloseableHttpClient getInstance() {
try {
HttpClientBuilder builder = HttpClients.custom().setMaxConnTotal(3)
.setMaxConnPerRoute(3);
builder.setRetryHandler(retryHandler());
builder.setServiceUnavailableRetryStrategy(new ServiceUnavailableRetryStrategy() {
int waitPeriod = 200;
@Override
public boolean retryRequest(final HttpResponse response, final int executionCount,
final HttpContext context) {
int statusCode = response.getStatusLine().getStatusCode();
return (((statusCode == 429) || (statusCode >= 300 && statusCode <= 399))
&& (executionCount < 3));
}
@Override
public long getRetryInterval() {
return waitPeriod;
}
});
httpclient = builder.build();
} catch (Exception e) {
//handle exception
}
return httpclient;
}
private static HttpRequestRetryHandler retryHandler() {
return (exception, executionCount, context) -> {
if (executionCount > maxRetries) {
// Do not retry if over max retry count
return false;
}
if (exception instanceof InterruptedIOException) {
// Timeout
return true;
}
if (exception instanceof UnknownHostException) {
// Unknown host
return false;
}
if (exception instanceof ConnectTimeoutException) {
// Connection refused
return false;
}
if (exception instanceof SSLException) {
// SSL handshake exception
return false;
}
HttpClientContext clientContext = HttpClientContext.adapt(context);
HttpRequest request = clientContext.getRequest();
boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
if (idempotent) {
// Retry if the request is considered idempotent
return true;
}
return false;
};
}
}
public CloseableHttpResponse uploadFile(){
CloseableHttpClient httpClient = GetClient.getInstance();
CloseableHttpResponse response = null;
try {
response = httpClient.execute(post);
} catch (Exception ex) {
//handle exception
}
return response;
}
谁能帮帮我。
【问题讨论】:
-
你是如何为这个类编写单元测试的?你有没有成功调用
uploadFile的测试? -
我也有兴趣看到
uploadFile()的简单运行测试。首先这里的结构,大量调用静态项,不利于编写单元测试,而且PowerMock不是我的朋友(WhiteBox除外)。我的总体策略是将 httpclient 构建为模拟,为正确的方法抛出异常(例如,使用Mockito.when(...).thenThrow(...).thenReturn(...))并让模拟使用Mockito.doCallRealMethod()作为正确的方法。但总而言之,没有看到uploadFile方法的工作版本,这只是一个猜测。
标签: java junit mockito apache-httpclient-4.x powermock