Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!

like image 933
Zmaja Avatar asked Nov 08 '22 08:11

Zmaja


1 Answers

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));
}
like image 74
Aldo Avatar answered Nov 15 '22 08:11

Aldo