我有一个接口,其方法需要一个
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 中的新功能是表达式的目标类型将用于推断其子表达式的类型参数。在 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
。运行时将尝试通过在将 null 返回值传递给 intValue
之前调用其上的 doStuff
方法来取消装箱,并引发异常。
因为我需要在我的最新项目中使用此功能(一度我们从 1.10.19 更新),只是为了让用户(已经在使用 mockito-core 版本 2.1.0 或更高版本)保持最新状态,上述答案中的静态方法应取自
ArgumentMatchers
类:
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.ArgumentMatchers.any;
如果您计划使 Mockito 工件保持最新状态,请记住这一点(可能从版本 3 开始),此类可能不再存在:
根据 2.1.0 及更高版本,org.mockito.Matchers 的 Javadoc 指出:
使用
。该类现已弃用,以便 避免与 Hamcrest 发生名称冲突 *org.mockito.ArgumentMatchers
班级。这个类可能会在 3.0 版本中被删除。org.hamcrest.Matchers
如果您想进一步阅读,我已经写了一篇关于 mockito 通配符的小文章。
您可以使用
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)
在最新版本的 Mockito 中,您可以使用任何(Foo.class)