所以现在我正在从 Mockito 1.* 迁移到 2.*,我不明白为什么在 doAnswer 中使用 getArgument() 时会出现转换问题。我的意思是当我尝试在其他方法参数中调用 getArgument() 或尝试在检索到的对象上链接方法时。这是适用于 mockito 1 的代码。
doAnswer(invocation -> {
try (InputStream inputStream = invocation.getArgumentAt(0, SomeResource.class).getResource().getInputStream()) {
IOUtils.copy(inputStream, invocation.getArgumentAt(1, OutputStream.class));
}
return null;
}).when(mockedService).downloadFile(any(), any());
迁移到 2.* 后将 getArgumentAt() 更改为 getArgument() 失败,因为找不到类型中的 "getResource()" 方法。此外,由于类型不兼容,从调用中获取第二个参数也不起作用。
doAnswer(invocation -> {
try (InputStream inputStream = invocation.getArgument(0).getResource().getInputStream()) {
IOUtils.copy(inputStream, invocation.getArgument(1));
}
return null;
}).when(mockedService).downloadFile(any(), any());
我不得不在第二个参数中更改为显式强制转换,或者显式保存到新引用,第一个参数也是如此。该代码有效:
doAnswer(invocation -> {
final SomeResource input = invocation.getArgument(0);
final OutputStream outputStream = invocation.getArgument(1);
try (InputStream inputStream = input.getResource().getInputStream()) {
IOUtils.copy(inputStream, outputStream);
}
return null;
}).when(mockedService).downloadFile(any(), any());
我不知道为什么。
getArgument
是一个泛型方法。它具有以下签名:
<T> T getArgument(int index)
请参阅javadoc。
这在Java 8之前是不可能的,它添加了广义目标类型推理,通常返回类型类被用作参数之一(就像使用Mockito 1.*的示例一样)。
因此,当您将结果分配给混凝土类型的变量时,不需要铸造,因为它可以推断出来。当你传递 is to IOUtils.copy()
时,它无法推断单个具体类型,因为 copy
方法已重载。如果将其传递给未重载的方法,则无需显式强制转换即可工作。