是否可以针对传递给Mockito模拟对象的参数进行查询



我现在正在学习Mockito,为了巩固我的学习,我正在做的一件事是将一个旧的JUnit测试从使用手工滚动的mock类转换为使用Mockito mock的测试。然而,我遇到了一个我不知道该如何处理的情况。

具体来说,我的测试单元构造了一个String,它作为方法调用中的参数传递给模拟对象。我想测试String是否构造正确。挑战在于String的一部分是一个散列密钥,它是在内部生成的,每次调用时都会更改。一个可行的解决方案是在我的控制下生成哈希,并注入一个用于测试执行的伪生成器。然而,这是一项相当艰巨的工作。

我的旧的手动模拟类会存储传递给它的参数,我可以在测试中查询这些参数。这使我能够通过以下方式查询String的开始和结束:

assertTrue(mockFtpClient.getFilePathAndName().startsWith("/data/inbound/XJSLGG."));
assertTrue(mockFtpClient.getFilePathAndName().endsWith(".pdf"));

这对我的品味来说已经足够了。所以我的问题是,是否可以使用Mockito来查询或获取传递给方法的参数,这样我就可以执行类似于上面的操作?

2011年6月24日更新:在这一点上,我已经排除了格农的回答。然而,从那以后,我发现了一种更适合我的东西,那就是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通常是更好的选择,就像我在这里所做的那样。

基本上,您需要在Mockito中使用argThat(),这允许您将HamcrestMatcher作为验证参数。以下是用于对传入参数进行自定义断言的代码:

@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) {
    }
}

您可以改为使用通用匹配器,或者使用多个通用匹配器的组合。

看看这个问题的公认答案mockito-how-to-make-a-method-return--an-argument-was-passed-it它将向您展示如何掌握传递给mock方法调用的参数。

相关内容

  • 没有找到相关文章

最新更新