簡體   English   中英

如何編寫 static void 方法的單元測試

[英]How to write unit test of a static void method

我面臨一個問題,我不知道如何編寫 static void 方法的單元測試。

我有一個 HttpHelper class,現在使用 Apache HttpClient。 代碼如下。

public class HttpHelper {
    private static CloseableHttpClient httpClient;

    public static void init() {
        httpClient = HttpClients.custom().setSSLContext(getDummySSL()).build();
    }

    public static void closeHttpClient() throws IOException {
        httpClient.close();
    }

    private static SSLContext getDummySSL() {
        ...omit
    }

    private static void send() {
        HttpGet httpGet = new HttpGet("https://someUrl.com");

        try(CloseableHttpResponse httpResponse = httpClient.execute(httpGet)) {
            if(httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                responseString = EntityUtils.toString(httpResponse.getEntity());
                // do something
            } else {
                throw new Exception();
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

所以在我的 main 中,我將調用HttpHelper.init()來初始化 httpClient。 每次我想發送請求時,我都會調用HttpHelper.send() 因為我不想每次都創建一個新的 httpClient 。 最后,我將調用HttpHelper.close()來關閉 httpClient。

我想知道如何測試那些 void 方法。 我的想法是在我的測試中創建一個CloseableHttpClient ,然后調用HttpHelper.init()來創建實際的。 然后比較我預期的和實際的是一樣的。 我對嗎?

由於變量和方法聲明為static。編寫單元測試有點困難。 有很多帖子說制作方法 static 是一種不好的做法。 但是在我的示例中,我不知道如何避免將它們聲明為 static 並保留單個CloseableHttpClient實例。

謝謝!

單實例保證主要通過 Singleton 模式解決。 單元測試的一個常見技巧是制作一個具有受保護可見性的構造函數,您可以在其中放置 arguments 進行測試。 class 最終可能看起來像這樣。

public class HttpHelper {
    private static HttpHelper INSTANCE = new HttpHelper();

    public static HttpHelper getInstance() {
        return INSTANCE;
    }


    private CloseableHttpClient httpClient;

    private HttpHelper() {
        SSLContext sslContext = getDummySSL();
        this(HttpClients.custom().setSSLContext(sslContext).build(), sslContext);
    }

    protected HttpHelper(CloseableHttpClient httpClient, SSLContext sslContext) {
        this.httpClient = httpClient;
    }

    public void closeHttpClient() throws IOException {
        httpClient.close();
    }

    private static SSLContext getDummySSL() {
        ...
    }

    private void send() {
        ...
    }
}

我還將createDummySSL getDummySSL是細節。

擁有 class 所以 static 是不好的,因為很難測試它。 我理解你為什么想要這個,但你可以擁有所有相同的好處:

public class HttpHelper {

    private static HttpHelper DEFAULT_INSTANCE = null;

    private CloseableHttpClient httpClient;

    public HttpHelper(CloseableHttpClient httpClient) {
        this.httpClient = httpClient;
    }

    public static void getDeafultInstance() { // this should probably be synchronised for thread safety
        if (DEFAULT_INSTANCE == null) {
            DEFAULT_INSTANCE = httpClient = HttpClients.custom().setSSLContext(getDummySSL()).build();
        }
        return DEAFULT_INSTANCE;
    }

    private static SSLContext getDummySSL() {
        ...omit
    }

    public void closeHttpClient() throws IOException {
        httpClient.close();
    }

    private void send() {
        HttpGet httpGet = new HttpGet("https://someUrl.com");

        try(CloseableHttpResponse httpResponse = httpClient.execute(httpGet)) {
            if(httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                responseString = EntityUtils.toString(httpResponse.getEntity());
                // do something
            } else {
                throw new Exception();
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

然后你可以像這樣對它進行單元測試:


public class HttpHelperTest {

    @Test
    public testSendsRequestToSomeUrl() {
        CloseableHttpClient httpClientMock = mock();
        when(httpClient.execute(any())).thenReturn(..http_response_where_stauts_code_is_ok..)
        HttpHelper httpHelper = new HttpHelper(httpClientMock)
        httpHelper.send()
        verify(httpClient).execute(new HttpGet("https://someUrl.com"))
    }

}

並像這樣在實際代碼中使用它:

HttpHelper.getDeafultInstance().send()

聚苯乙烯

如果你有某種可用的依賴注入框架,那么你可以完全擺脫 static 方法。

暫無
暫無

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

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