使用模拟对象时测试粒度



我有struts1动作,想单独测试它。这个动作的作用如下:

  • 使用请求
  • 中的参数加载数据
  • 构建此数据的基于xml的表示
  • 将此响应直接发送到客户端

我使用jMock进行测试,但这里有一个疑问。我的第一个测试是

public void shouldActionInvocationPrintValidResponse() {
    ProcessingAction action = new ProcessingAction();
    DBService service = mock(DBService.class);
    List records = new ArrayList();
    when(service.loadData()).thenReturn(records);
    ResponseBuilder builder = mock(ResponseBuilder.class);
    when(builder.buildResponse(records)).thenReturn("fake response");
    action.execute(null, null, null, null);
    assertEquals("fake response", writer.getContentWritten());
}

我的prod代码求值为:

public String execute(...) {
    List recordsList = service.loadData();
    String response = responseBuilder.buildResponse(recordsList);
    response.getWriter().print(response);
}

我怀疑这样的测试在这里是不是太大了。我在这里检查整个成功流程。难道不应该有单独的测试在它们自己的测试中检查每个依赖项调用吗?

我想知道,因为我对这个测试的名字有麻烦。我一开始的想法是这样的

shouldFetchDataThenFormatThemAndSendResponse

由于这是所有测试所做的,因此名称显示它可能做得太多了(例如,看看测试名称中的"one_answers")

我应该立即编写整个测试,还是只是一步一步地添加依赖调用?

编辑:提供了测试和操作的详细代码。

我认为你是对的。shouldFetchDataThenFormatThemAndSendResponse这说明了一切。在您的测试命名中,您正在谈论实现细节。这就是您应该如何编写第一个测试。

ProcessingAction action = new ProcessingAction();
Response response = action.execute();
assertEquals(true, response.IsValid);

尝试: shouldGetResponseWhenActionExecuted

现在您可以看看如何在执行操作时获得响应。

我敢跟你打赌,你肯定没有TDD。

记住:意图高于实现!别再露出你的紧身内衣了。

没有看到代码很难回答你的问题,但是我会给它一个尝试。对于要成为Unit测试的测试,它不应该运行除被测试类中的代码以外的代码。如果您已经模拟了操作调用的所有其他类,并且您正在验证的内容仅在被测试的类中完成,那么测试不是太大。我已经编写了包含大量验证语句的单元测试,因为所有的事情都发生在被测类中,这是由于单个方法的调用。

我的单元测试规则是:1. 只在被测试的类中执行代码2.
每个测试方法只输入一次被测试的方法

我同意John B。此外,如果您使用Mock Test Runner并正确地编写它,则可能不需要断言。

最新更新