Java 我使用mock的方法正确吗?
我有一些遗留的东西,想通过测试来覆盖它。 我不知道如何使用mock测试以下方法Java 我使用mock的方法正确吗?,java,unit-testing,mocking,Java,Unit Testing,Mocking,我有一些遗留的东西,想通过测试来覆盖它。 我不知道如何使用mock测试以下方法 public String listTransactions(Request request, Response response) { String transactionFamily = request.get("transactionFamily"); List transactions = service.fetchTransactions(transactionFamily); re
public String listTransactions(Request request, Response response) {
String transactionFamily = request.get("transactionFamily");
List transactions = service.fetchTransactions(transactionFamily);
responseBuilder.addElement("collection", transactions);
responseBuilder.addElement("token", tokenGenerator.next());
String formattedResponse = responseBuilder.build();
response.send(formattedResponse);
return null;
}
我的第一个方法是:
public void testResponseIsBuilt() {
request = stub(Request.class);
request.method("get").with("transactionFamily").willReturn("dummyFamily");
response = mock(Response.class);
response.mehod("send").called(once());
service = stub(TransactionService.class);
service.method("fetchTransactions").willReturn(testTransactions);
responseBuilder = mock(ResponseBuilder.class);
responseBuilder.method("addElement").called(once()).with("collection", testTransactions);
responseBuilder.method("addElement").called(once()).with("token", sampleToken);
responseBuilder.method("build").called(once());
responder.setService(service);
responder.setResponseBuilder(responseBuilder);
responder.listTransactions(request, response);
}
我知道单个测试用例应该只涵盖SUT的一个方面。考虑到这一点,我可以想象以下一组测试:
- TestTransactionFetchedForFamily
- testTransactionsAddedToResponse
- testTokenSetInResponse
- testFormattedResponseBuilt
- 测试响应
- 存根请求
- 存根服务
- 模拟响应构建器,具有3个期望值(2个附加元素和1个构建)
我怀疑我忽略了在这里编写单元测试的一些要点。这些测试有些过火了。似乎您的方法的责任是正确设置和发送响应(从代码命名判断可能更好,比如,它现在列出了哪些事务?)。这就是这里应该测试的 编辑: 再看一眼,大部分工作似乎都是由
responseBuilder
完成的,剩下的代码只是对其进行了设置。所以,您真正可以在这里测试的是它是否提供了预期的数据(即一个或两个测试),以及最终是否发送了响应(第二个/第三个测试)。请注意,检查是否调用了.build
,这并不是必需的,因为它的缺失将导致响应发送测试失败
这意味着您需要模拟和验证responseBuilder
(.add
方法)和response
(.send
)上的期望。测试响应格式属于responseBuilder
test,就像测试事务是否正确获取属于service
测试一样
(您也可以验证service
是用正确的参数调用的,因为它是硬编码的,但这只是在您想非常小心的情况下)
总的来说,我会剔除测试1和测试4,并将重点放在剩下的测试上
为了验证这些期望,您必须去掉剩余的依赖项。这是不可能的。您需要在决定您愿意编写多少代码来测试单行代码(以及是否值得)之间找到最佳点。测试套件应包含设置方法,其中应提及请求、服务。这将确保对所有测试用例重用变量。模块化程度越高,得到的响应越细粒度。希望这能对您有所帮助。但为了设定一些模拟预期,我需要在测试中揭示一些内部内容,对吗?为了获得正确的响应格式,我需要准备好responseBuilder,以便为其提供事务和令牌,所以我需要再次展示内部结构。还是我完全迷路了?@grafthez:检查我的编辑-你说得对,你要测试的是responseBuilder是否提供了正确的数据以及是否发送了响应。其他测试属于不同的类。你肯定是对的。我在这里已经讲得很清楚了——在实际实现中,它将转到setUp()。我的问题有点不同:我的实现执行“abcd”,要测试“b”,需要设置“a”。为了测试“c”期望值,我需要设置“AB”,等等……JUnit是为了测试一个流,所以据我所知,您需要为完整的测试用例测试d,并给出c、b和a的断言。您的测试套件应该只包含一个测试流的测试。