Mocking response for HTTPGet in Java

user_mda picture user_mda · Feb 3, 2017 · Viewed 8.5k times · Source

I have to mock a request to an API that returns a response with JSON entity For this I mock the get request as well as the JSON object

public class RestTest {
    static JSONObject job;
    static JSONArray portsArray;
    static JSONArray routesArray;
    static JSONObject routeObject;
    private static final HttpClient  client = mock(DefaultHttpClient.class);
    private static final HttpGet  get = mock(HttpGet.class);
    private static final HttpResponse response = mock(CloseableHttpResponse.class);
    private static  HttpEntity entity = mock(HttpEntity.class);

    @BeforeClass
    public static void setup() throws ClientProtocolException, IOException, JSONException {
        HttpGet getRoute = new HttpGet("api/to/access");
        getRoute.setHeader("Content-type", "application/json");
        JSONObject routesJson = new JSONObject();
        routesJson.put("","");
        when(response.getEntity()).thenReturn(entity);
        when(response.getEntity().getContent().toString()).thenReturn(routesJson.toString());
        when(client.execute(getRoutes)).thenReturn(response);
    }
}

This returns a null pointer at when(response.getEntity().getContent().toString()).thenReturn(routesJson.toString());

How do I properly mock the JSON object so when the real request is executed it returns the mocked JSON?

I am unable to set entity.setContent() as seen in examples since the method does not exist.

Answer

Christopher Schneider picture Christopher Schneider · Feb 3, 2017

Well, let 's look at these two lines.

    when(response.getEntity()).thenReturn(entity);
    when(response.getEntity().getContent().toString()).thenReturn(routesJson.toString());

Which do you think takes precedence? I don't know, and I wouldn't count on it being well defined, regardless of what any docs say.

What's probably happening:

You say

   when(response.getEntity()).thenReturn(entity);

When this happens:

   response.getEntity().getContent().toString()

You're probably making the call

entity.getContent().toString()

which would definitely cause a NPE, since you haven't defined anything for entity.getContent()

I'd suggest you use RETURNS_DEEP_STUBS if you have to do your test this way. So

 private static final HttpResponse response = mock(CloseableHttpResponse.class, 
Mockito.RETURNS_DEEP_STUBS);

You can then skip manually mocking HttpEntity completely, and just do

when(response.getEntity().getContent().toString()).thenReturn(routesJson.toString());