Java 可以对传递给Mockito mock对象的参数进行查询吗?

Java 可以对传递给Mockito mock对象的参数进行查询吗?,java,mockito,Java,Mockito,我现在正在学习Mockito,我正在做的巩固学习的一件事是将一个旧的JUnit测试从使用手动的mock类转换为使用Mockito mock的类。然而,我遇到了一个我不知道如何处理的情况 具体地说,我的测试单元构造了一个字符串,该字符串作为方法调用中的参数传递给模拟对象。我想测试字符串的构造是否正确。挑战在于字符串的一部分是一个哈希键,它是在内部生成的,每次调用时都会更改。一个可行的解决方案是在我的控制下生成散列,并为测试执行注入一个虚拟生成器。然而,这是一项相当艰巨的工作 我的旧的手动模拟类将存

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

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

我的旧的手动模拟类将存储传递给它的参数,我可以在测试中查询这些参数。这允许我通过以下方式查询
字符串的开始和结束:

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));
ArgumentCaptor fileNameArgument=ArgumentCaptor.forClass(String.class);
验证(mockFtpClient.putFileOnServer(fileNameArgument.capture());
assertTrue(fileNameArgument.getValue().startsWith(开始文件名)&&
fileNameArgument.getValue().endsWith(END_FILE_NAME));

javadoc for Mockito声明,当您有一次性的特定参数匹配需求时,
ArgumentCaptor
通常是更好的选择,正如我在这里所做的。

看看这个问题的公认答案,它将向您展示如何获得传递给模拟方法调用的参数。

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

@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) {
    }
}
@测试
public void testname()引发异常{
HashReceiver=mock(HashReceiver.class);
接收者集(“散列”);
验证(receiver.set)(argThat(newhashmatcher());
}
类HashMatcher扩展了BaseMatcher{
@凌驾
公共布尔匹配(对象项){
字符串哈希=(字符串)项;
if(hash.startsWith(“/data/inbound/XJSLGG.”)和&hash.endsWith(“.pdf”))
返回true;
返回false;
}
}
//嘲弄
类哈希接收器{
公共无效集(字符串哈希){
}
}

您可以使用泛型匹配器,或者泛型匹配器的组合。

不错,但使用应答对象获取输入参数对我来说似乎有点落后,我不完全确定它是否能与我的void方法签名一起工作。谢谢你!我以前不知道
答案
。谢谢Gnon,我认为这个解决方案非常适合我的需要。遗憾的是,它有这么多额外的代码,但这不是常见的场景。在这里可以找到argThat()方法:。您的导入应该是
import static org.mockito.Matchers.argThat感谢更新,我不知道ArgumentCaptor。ArgumentCaptor将改变我的(编码)生活!