如何使用Mockito模拟方法调用

时间:2016-12-10 18:41:24

标签: java unit-testing junit mockito

使用Mockito进行单元测试时遇到以下问题:

我有这个方法:

@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();
}

我只想测试这个方法,而不是内部调用的processRequestMethod(我想在anthoer测试中单独测试),所以我需要模拟它并在结束时检查测试已经调用了OutputStream类的方法写入和关闭。

我尝试了两种方法,但没有一方没有运气:

@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();
}

使用上面的代码,processRequest方法没有被调用,但是我想要测试的句柄方法也没有,所以测试失败了:

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

说根本没有调用此方法。

但是,如果我在创建模拟时添加参数CALL_REAL_METHODS,请执行以下操作:

@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();
}

然后,当方法执行此行时,实际上会调用我想要跳过的processRequest方法:

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

任何可能出错的线索?

1 个答案:

答案 0 :(得分:3)

在您的测试中而不是

1[Foo]' to type 'System.Collections.Generic.List

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

Mockito.spy()

您可能需要 RequestHandler requestHandler=spy(RequestHandler.class); doReturn(result).when(requestHandler).processRequest(httpRequest); 表单而不是doReturn().when(),因为第一个执行该方法,而后者则执行。{/ p>

另一方面,我更愿意将when().thenReturn()移到另一个类,在那里你可以将一个实例注入processRequest(),这样可以使模拟更直接......