Mocking HttpClient requests with mockito

user_mda picture user_mda · Dec 30, 2016 · Viewed 8.4k times · Source

I have the following code that I wish to test using Junit and Mockito.

Code to test:

    Header header = new BasicHeader(HttpHeaders.AUTHORIZATION,AUTH_PREAMBLE + token);
    List<Header> headers = new ArrayList<Header>();
    headers.add(header);
    HttpClient client = HttpClients.custom().setDefaultHeaders(headers).build();
    HttpGet get = new HttpGet("real REST API here"));
    HttpResponse response = client.execute(get);
    String json_string_response = EntityUtils.toString(response.getEntity());

And the Test

protected static HttpClient mockHttpClient;
protected static HttpGet mockHttpGet;
protected static HttpResponse mockHttpResponse;
protected static StatusLine mockStatusLine;
protected static HttpEntity mockHttpEntity;





@BeforeClass
public static void setup() throws ClientProtocolException, IOException {
    mockHttpGet = Mockito.mock(HttpGet.class);
    mockHttpClient = Mockito.mock(HttpClient.class);
    mockHttpResponse = Mockito.mock(HttpResponse.class);
    mockStatusLine = Mockito.mock(StatusLine.class);
    mockHttpEntity = Mockito.mock(HttpEntity.class);

    Mockito.when(mockHttpClient.execute(Mockito.isA(HttpGet.class))).thenReturn(mockHttpResponse);
    Mockito.when(mockHttpResponse.getStatusLine()).thenReturn(mockStatusLine);
    Mockito.when(mockStatusLine.getStatusCode()).thenReturn(HttpStatus.SC_OK);
    Mockito.when(mockHttpResponse.getEntity()).thenReturn(mockHttpEntity);

}


@Test
underTest = new UnderTest(initialize with fake API (api));
//Trigger method to test

This gives me an error:

java.net.UnknownHostException: api: nodename nor servname provided, or not known

Why does t not mock the 'client.execute(get)' call as is in the set up?

Answer

GhostCat picture GhostCat · Dec 30, 2016

What you have so far is:

mockHttpClient = Mockito.mock(HttpClient.class);
Mockito.when(mockHttpClient.execute(Mockito.isA(HttpGet.class))).thenReturn(mockHttpResponse)

So there is a mock that should react to a call to execute().

And then you have:

1) underTest = new UnderTest(initialize with fake API (api));
2) // Trigger method to test

The problem is: something is either wrong with your line 1 or with line 2 in your setup. But we can not tell you that; because you are not providing that code to us.

The thing is: in order for your mock object to be of use, it needs to be used by underTest somehow. So when you are doing the init stuff wrong somehow, then underTest is not using the mocked thing, but some "real" thing.