目前我正在学习Mockito,为了巩固我的学习,我所做的事情之一就是将一个旧的JUnit测试从使用手工滚动的模拟类转换为使用Mockito模拟的测试。然而,我遇到了一个我不知道如何处理的情况。
具体来说,我的被测试单元构建了一个String
,它作为方法调用中的一个参数传递给模拟对象。我想测试String
的构造是否正确。挑战在于,String
的一部分是哈希键,它是内部生成的,每次调用都会发生变化。一个可行的解决方案是将哈希生成置于我的控制之下,并为测试执行注入一个虚拟生成器。然而,这是一个相当多的工作。
我的旧手卷模拟类将存储传递给它的参数,我可以在测试中查询这些参数。这使我可以通过以下方式查询String
的开始和结束:
assertTrue(mockFtpClient.getFilePathAndName().startsWith("/data/inbound/XJSLGG."));
assertTrue(mockFtpClient.getFilePathAndName().endsWith(".pdf"));
对我的口味来说,这是一个足够的考验。所以我的问题是,是否可以使用Mockito查询或获取传递给方法的参数,以便执行类似于上面的操作?
更新24/06/2011:在这一点上,我已经排除了侏儒的回答。然而,从那以后,我发现了一些对我更有用的东西。即ArgumentCaptor
.下面是它的工作原理:
ArgumentCaptor<String> fileNameArgument = ArgumentCaptor.forClass(String.class);
verify(mockFtpClient).putFileOnServer(fileNameArgument.capture());
assertTrue(fileNameArgument.getValue().startsWith(START_FILE_NAME) &&
fileNameArgument.getValue().endsWith(END_FILE_NAME));
Mockito的javadoc声明,当您有一个一次性的特定参数匹配需求时,ArgumentCaptor
通常是一个更好的选择,就像我在这里所做的那样。
发布于 2011-06-23 17:49:02
基本上,您需要在Mockito中使用argThat(),这允许您将Hamcrest Matcher作为验证参数。下面是用于对传入参数进行自定义断言的代码:
@Test
public void testname() throws Exception {
HashReceiver receiver = mock(HashReceiver.class);
receiver.set("hash");
verify(receiver).set(argThat(new HashMatcher()));
}
class HashMatcher extends BaseMatcher<String> {
@Override
public boolean matches(Object item) {
String hash = (String) item;
if (hash.startsWith("/data/inbound/XJSLGG.") && hash.endsWith(".pdf"))
return true;
return false;
}
}
// Mocked
class HashReceiver {
public void set(String hash) {
}
}
您可能可以使用泛型匹配器,或者使用泛型匹配器的组合。
发布于 2011-06-23 16:20:34
看看这个问题的公认答案,mockito-how-to-make-a-method-return-an-argument-that-was-passed-to-it,它将向您展示如何获得传递给模拟方法调用的参数。
https://stackoverflow.com/questions/6457245
复制相似问题