How can I create a CloseableHttpResponse object to help testing?

Popcorn picture Popcorn · Nov 7, 2013 · Viewed 23.9k times · Source

I'm trying to construct a CloseableHttpResponse mock object to be returned in one of my unit tests, but there's no constructor for it. I found this DefaultHttpResponseFactory, but it only makes a HttpResponse. What's a simple way to construct a CloseableHttpResponse? Do I need to call execute() in my test and then set the statusLine and entity? That seems like a weird approach.

Here's the method I'm trying to mock:

public static CloseableHttpResponse getViaProxy(String url, String ip, int port, String username,
                                                String password) {
    CredentialsProvider credsProvider = new BasicCredentialsProvider();
    credsProvider.setCredentials(
            new AuthScope(ip, port),
            new UsernamePasswordCredentials(username, password));
    CloseableHttpClient httpclient = HttpClients.custom()
            .setDefaultCredentialsProvider(credsProvider).build();
    try {
        RequestConfig config = RequestConfig.custom()
                .setProxy(new HttpHost(ip, port))
                .build();
        HttpGet httpGet = new HttpGet(url);
        httpGet.setConfig(config);

        LOGGER.info("executing request: " + httpGet.getRequestLine() + " via proxy ip: " + ip + " port: " + port +
                " username: " + username + " password: " + password);

        CloseableHttpResponse response = null;
        try {
            return httpclient.execute(httpGet);
        } catch (Exception e) {
            throw new RuntimeException("Could not GET with " + url + " via proxy ip: " + ip + " port: " + port +
                    " username: " + username + " password: " + password, e);
        } finally {
            try {
                response.close();
            } catch (Exception e) {
                throw new RuntimeException("Could not close response", e);
            }
        }
    } finally {
        try {
            httpclient.close();
        } catch (Exception e) {
            throw new RuntimeException("Could not close httpclient", e);
        }
    }
}

Here's the mock code using PowerMockito:

    mockStatic(HttpUtils.class);
    when(HttpUtils.getViaProxy("http://www.google.com", anyString(), anyInt(), anyString(), anyString()).thenReturn(/*mockedCloseableHttpResponseObject goes here*/)

Answer

nnguyen07 picture nnguyen07 · Jan 20, 2014

Follow these steps may help:

1.mock it (ex. mockito)

CloseableHttpResponse response = mock(CloseableHttpResponse.class);
HttpEntity entity = mock(HttpEntity.class);

2.apply some rules

when(response.getStatusLine()).thenReturn(new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "FINE!"));
when(entity.getContent()).thenReturn(getClass().getClassLoader().getResourceAsStream("result.txt"));
when(response.getEntity()).thenReturn(entity);

3.use it

when(httpClient.execute((HttpGet) any())).thenReturn(response);