fgonzalez
fgonzalez

Reputation: 3887

How to mock a method call using Mockito

I have the following problem using Mockito for unit testing:

I have this method:

@Override
public void handle(HttpExchange httpRequest) throws IOException {
    Object[] outputResult = processRequest(httpRequest);
    String response = (String) outputResult[0];
    Integer responseCode = (Integer) outputResult[1];
    httpRequest.sendResponseHeaders(responseCode, response.length());
    OutputStream os = httpRequest.getResponseBody();
    os.write(response.getBytes());
    os.close();
}

And I want only to test this method, not the processRequestMethod that is called internally (that I would like to test separately in anthoer test), so I need to mock it and to check at the end of the test that the methods write and close of the OutputStream class have been called.

I have tried two ways, but no luck with none of them:

@Test
public void handleTest() throws IOException {
    RequestHandler requestHandler=mock(RequestHandler.class);
    String response = "Bad request";
    int responseCode = HttpURLConnection.HTTP_BAD_REQUEST;
    Object[] result={response,responseCode};
    when(requestHandler.processRequest(anyObject())).thenReturn(result);
    when (httpExchange.getResponseBody()).thenReturn(outputStream);
    requestHandler.handle(httpExchange);
    Mockito.verify(outputStream,times(1)).write(anyByte());
    Mockito.verify(outputStream,times(1)).close();
}

With the code above, the processRequest method is not called, but neither is the handle method that I want to test, so the test is failing in the line:

Mockito.verify(outputStream,times(1)).write(anyByte());

Saying that this method was not called at all.

However if I add the parameter CALL_REAL_METHODS when creating the mock, like this:

@Test
public void handleTest() throws IOException {
    RequestHandler requestHandler=mock(RequestHandler.class,CALLS_REAL_METHODS);
    String response = "Bad request";
    int responseCode = HttpURLConnection.HTTP_BAD_REQUEST;
    Object[] result={response,responseCode};
    when(requestHandler.processRequest(anyObject())).thenReturn(result);
    when (httpExchange.getResponseBody()).thenReturn(outputStream);
    requestHandler.handle(httpExchange);
    Mockito.verify(outputStream,times(1)).write(anyByte());
    Mockito.verify(outputStream,times(1)).close();
}

Then the processRequest method that I want to skip is actually called when the method executes this line:

when(requestHandler.processRequest(anyObject())).thenReturn(result);

Any clues of what can be wrong?

Upvotes: 1

Views: 2415

Answers (1)

Timothy Truckle
Timothy Truckle

Reputation: 15634

in your test instead of

RequestHandler requestHandler=mock(RequestHandler.class,CALLS_REAL_METHODS);

use Mockito.spy():

      RequestHandler requestHandler=spy(RequestHandler.class);
      doReturn(result).when(requestHandler).processRequest(httpRequest);

you may want the doReturn().when() form rather than the when().thenReturn() because the first does not execute the method whereas the latter does.


On the other hand I'd prefer to move processRequest() to another class where you can inject an instance of into RequestHandler which would make mocking more straight...

Upvotes: 3

Related Questions