Zmaja
Zmaja

Reputation: 61

Mock Apache HTTPClient with ResponseHandler in Mockito

I've been trying to mock Apache HTTPClient with ResponseHandler, in order to test my service, using Mockito. The method in question is:

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

where "responseHandler" is a 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 "";
    }
};

Can somebody suggest how can I accomplish this? I want to mock "execute()" method, but I don't want to mock the "responseHandler" (I wan't to test the existing one).

Thanks!

Upvotes: 6

Views: 2262

Answers (1)

Aldo
Aldo

Reputation: 546

You can mock HttpClient and use Mockito's thenAnswer() method. For example, something like:

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

Upvotes: 3

Related Questions