首页 > 解决方案 > 如何编写静态 void 方法的单元测试

问题描述

我面临一个问题,我不知道如何编写静态 void 方法的单元测试。

我现在有一个使用 Apache HttpClient 的 HttpHelper 类。代码如下。

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();
        }
    }
}

因此,在我的主要部分中,我将调用HttpHelper.init()初始化 httpClient。每次我想发送请求时,我都会打电话HttpHelper.send()。因为我不想每次都创建一个新的 httpClient 。最后,我会调用HttpHelper.close()关闭httpClient。

我想知道如何测试那些 void 方法。我的概念是CloseableHttpClient在我的测试中创建一个,然后调用HttpHelper.init()创建实际的。然后比较我的预期和实际的是否相同。我对吗?

由于变量和方法被声明为静态。编写单元测试有点困难。有很多帖子说将方法设为静态是一种不好的做法。但是在我的示例中,我不知道如何避免将它们声明为静态并保留单个CloseableHttpClient实例。

谢谢!

标签: javaunit-testingmockitohttpclientjunit5

解决方案


单实例保证主要通过单例模式解决。单元测试的一个常见技巧是创建一个具有受保护可见性的构造函数,您可以在其中放置参数进行测试。这门课终于可以变成这样了。

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() {
        ...
    }
}

我也会将其重命名为getDummySSLcreateDummySSL但这是细节。


推荐阅读