【问题标题】:Mock Apache HTTPClient with ResponseHandler in Mockito在 Mockito 中使用 ResponseHandler 模拟 Apache HTTPClient
【发布时间】:2018-04-05 11:48:57
【问题描述】:

我一直在尝试使用 ResponseHandler 模拟 Apache HTTPClient,以便使用 Mockito 测试我的服务。有问题的方法是:

String response = httpClient.execute(httpGet, responseHandler);

其中“responseHandler”是一个ResponseHandler:

ResponseHandler<String> responseHandler = response -> {
    int status = response.getStatusLine().getStatusCode();
    if (status == HttpStatus.SC_OK) {
        return EntityUtils.toString(response.getEntity());
    } else {
        log.error("Accessing API returned error code: {}, reason: {}", status, response.getStatusLine().getReasonPhrase());
        return "";
    }
};

有人可以建议我如何做到这一点吗?我想模拟“execute()”方法,但不想模拟“responseHandler”(我不想测试现有的)。

谢谢!

【问题讨论】:

    标签: java mocking mockito apache-httpcomponents


    【解决方案1】:

    您可以模拟 HttpClient 并使用 Mockito 的 thenAnswer() 方法。例如,类似:

    @Test
    public void http_ok() throws IOException {
        String expectedContent = "expected";
    
        HttpClient httpClient = mock(HttpClient.class);
        when(httpClient.execute(any(HttpUriRequest.class), eq(responseHandler)))
                .thenAnswer((InvocationOnMock invocation) -> {
                    BasicHttpResponse ret = new BasicHttpResponse(
                            new BasicStatusLine(HttpVersion.HTTP_1_1, HttpURLConnection.HTTP_OK, "OK"));
                    ret.setEntity(new StringEntity(expectedContent, StandardCharsets.UTF_8));
    
                    @SuppressWarnings("unchecked")
                    ResponseHandler<String> handler
                            = (ResponseHandler<String>) invocation.getArguments()[1];
                    return handler.handleResponse(ret);
                });
    
        String result = httpClient.execute(new HttpGet(), responseHandler);
    
        assertThat(result, is(expectedContent));
    }
    

    【讨论】:

    • 什么是 eq(responseHandler) 中的“responseHandler”?我没有看到它在任何地方定义。你能详细说明一下吗?谢谢...
    • 这是@Zmaja 在问题中定义的responseHandler 变量。我编写测试的方式假设它被定义为测试类中的实例变量,但当然您可以将其定义为局部变量。
    • 感谢您的回复!在那种情况下,它不会将响应传递给我们定义的 responseHandler(在我们的测试类或本地测试方法中)吗?而且,主类中定义的实际 responseHandler 永远不会被调用,并且会被排除在覆盖范围之外。我错过了什么吗?
    • responseHandler 是被测试的对象。原始问题中的那个只是一个例子,我写的测试只是说明了如何模拟一个调用其handleResponse 方法的HTTPClient。在现实世界中,应该使用正在测试的实际ResponseHandler 来调整示例。
    • 好的。我也有单元测试场景,我在其中模拟了执行方法,但想调用实际的 responseHandler。将尝试使用您的代码。谢谢!
    猜你喜欢
    • 2013-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-07
    • 2018-07-31
    • 1970-01-01
    • 2018-04-03
    • 1970-01-01
    相关资源
    最近更新 更多