Using Mockito for HTTP Client

java, json, mocking, mockito

Solution

You might have to mock `HttpClient` and `HttpResponse`, if they're interfaces (although, depending on your library, you could use `MockHttpClient` or `MockHttpResponse`), but you shouldn't be mocking anything else.

Why?

The mock is establishing expected output behavior on classes that we cannot make concrete, or rather, classes that we want to behave in a certain way for this particular instance of a test. You want to ensure that you get the correct response back from a mock `HttpClient`, and that when `response.getEntity()` is called, that it gives back a meaningful `HttpEntity`. You can elect to mock that out or not; I personally wouldn't, as the mock doesn't add any extra value (except to perhaps verify that a particular method was called).

Everything else is a concrete implementation - you should be allowing the other objects to interact with the results of the previously mocked elements to ensure that they behave as they would if there were no mocks.

Actually...you really can't mock those unless you pass them in or inject them in some way. I would strongly discourage you from attempting to mock any `new`ed objects in that method.

You don't specify what you're asserting, but I would expect that it's your `JSONObject` in some capacity. I'd assert that what you expected to be placed into it actually made it into the JSON object, and also verify that your mocked objects were called and invoked in the way you expected them to be.

Your annotation `@Mock` is not cascading, by the way - you have to annotate all mocked fields with `@Mock`, then either annotate the test class with `@RunWith(MockitoJunitRunner.class)`, or use `MockitoAnnotation.initMocks(this)` (one or the other; both aren't required except under edge cases). If you choose the annotations, don't forget `@InjectMocks` on your test object.

Lastly, your `when` conditions do what I would expect them to do - those should be fine.

Problem

I have a stubbed JSON OBJECT but need to mock the following using Mockito: ``` HttpResponse response = defaultHttpClient.execute(postRequest); BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); StringBuilder result = new StringBuilder(); while ((line = rd.readLine()) != null) { result.append(line); } JSONObject jsonResponseObject = new JSONObject(result.toString()); ``` I have created the following Mocks: ``` @Mock private HttpClient mockHttpClient; private HttpPost mockHttpPost; private HttpResponse mockHttpResponse; private HttpEntity mockHttpEntity; private InputStream mockInputStream; private InputStreamReader mockInputStreamReader; private BufferedReader mockBufferedReader; ``` And have the following `when` statements: ``` Mockito.when(mockHttpClient.execute(mockHttpPost)).thenReturn(mockHttpResponse); Mockito.when(mockHttpResponse.getEntity()).thenReturn(mockHttpEntity); Mockito.when(mockHttpEntity.getContent()).thenReturn(mockInputStream); ``` Question: Do I need to create all these 'when' statements and if yes then which other ones do I need to create to be able to get to the stubbed JSON? Any suggestions pls? Thanks

Original source