簡體   English   中英

如何使用junit對HttpClient重試邏輯進行單元測試

[英]How to unit test HttpClient retry logic using junit

我正在使用apache http客戶端來使用服務,並且我需要根據超時和響應代碼重試請求。 為此,我實現了以下代碼。 如何為超時和響應代碼場景編寫用於重試邏輯的junit測試。 我想以這樣一種方式編寫單元測試:當我發送任何發布/獲取請求(如果它返回429錯誤代碼響應)或任何TimeOutException時,我應確保重試邏輯正確執行。 我對如何編寫重試邏輯的單元測試一無所知。 通過谷歌搜索,我發現了以下鏈接,但對我沒有幫助。

單元測試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;    
   }

誰可以幫我這個事。

您的httpClient有一個“目標” URL,例如localhost:1234。 您想要測試的是您的重試代碼,因此您不應該觸摸httpClient本身(因為它不是您的組件,因此您也不需要測試它。)

因此,當前的問題是,當您的localhost:1234響應出現問題時,您希望看到將運行的重試邏輯(而不是您的實現。如果沒有正確配置,將運行其重試問題)。您要做的就是模擬“ localhost:1234”!

該工具http://wiremock.org/是執行此操作的理想選擇。 您可以為目標網址創建存根,並根據幾乎任何喜歡的內容給出一系列響應。

您的代碼應類似於調用uploadFile之前的樣子

    stubFor(post(urlEqualTo("/hash"))
        .willReturn(aResponse()
            .withStatus(200)
            .withBody(externalResponse)));

並在調用uploadFile

並驗證步驟以驗證到達模擬端點的模擬請求

    Assert.assert* //... whatever you want to assert in your handlers / code / resposnes
    verify(postRequestedFor(urlEqualTo("/hash")));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM