我有一个接口,该接口带有一个需要 Foo
数组的方法:
public interface IBar {
void doStuff(Foo[] arr);
}
我正在使用 Mockito 模拟这个接口,我想断言 doStuff()
被调用,但我不想验证传递了什么参数 - “不在乎”。
如何使用通用方法 any()
而不是 anyObject()
编写以下代码?
IBar bar = mock(IBar.class);
...
verify(bar).doStuff((Foo[]) anyObject());
这应该工作
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
verify(bar).DoStuff(any(Foo[].class));
从 Java 8 开始,您可以使用无参数 any
方法,编译器将推断类型参数:
verify(bar).doStuff(any());
解释
Java 8 中的新功能是表达式的 target type 将用于推断其子表达式的类型参数。在 Java 8 之前,只有用于类型参数推断的方法的参数(大部分时间)。
在这种情况下,doStuff
的参数类型将是 any()
的目标类型,并且将选择 any()
的返回值类型以匹配该参数类型。
添加此机制主要是为了能够编译 lambda 表达式,但它总体上改进了类型推断。
原始类型
不幸的是,这不适用于原始类型:
public interface IBar {
void doPrimitiveStuff(int i);
}
verify(bar).doPrimitiveStuff(any()); // Compiles but throws NullPointerException
verify(bar).doPrimitiveStuff(anyInt()); // This is what you have to do instead
问题是编译器会将 Integer
推断为 any()
的返回值类型。 Mockito 不会意识到这一点(由于类型擦除)并返回引用类型的默认值,即 null
。运行时将尝试通过在将其传递给 doStuff
之前调用其上的 intValue
方法来拆箱 null 返回值,并引发异常。
any
方法应该可以正常工作。您不会为正常工作的事情查找答案!
any()
一起使用,但可以与 anyBoolean()
一起使用,您答案的最后一部分很好地阐明了这一点。
您可以为此使用 Mockito.isA()
:
import static org.mockito.Matchers.isA;
import static org.mockito.Mockito.verify;
verify(bar).doStuff(isA(Foo[].class));
http://site.mockito.org/mockito/docs/current/org/mockito/Matchers.html#isA(java.lang.Class)
因为我需要将此功能用于我的最新项目(我们曾从 1.10.19 更新),只是为了留住用户(已经在使用 mockito-core 2.1.0 或更高版本 ) 最新,上述答案中的静态方法应取自 ArgumentMatchers
类:
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.ArgumentMatchers.any;
如果您计划从版本 3 开始使您的 Mockito 人工制品保持最新,请记住这一点,此类可能不再存在:
根据 2.1.0 及更高版本,org.mockito.Matchers 的 Javadoc 声明:
使用 org.mockito.ArgumentMatchers。此类现在已弃用,以避免与 Hamcrest * org.hamcrest.Matchers 类发生名称冲突。此类可能会在 3.0 版中被删除。
如果您想进一步阅读,我已经写了一篇关于 mockito wildcards 的小文章。
verify(bar).DoStuff(any[Array[Foo]])