使用Mockito的通用“ any()”方法


194

我有一个接口,该方法需要一个数组Foo

public interface IBar {
  void doStuff(Foo[] arr);
}

我正在使用Mockito来模拟此接口,我想断言该接口已doStuff()被调用,但是我不想验证传递了什么参数-“无关”。

如何使用any()通用方法而不是编写以下代码anyObject()

IBar bar = mock(IBar.class);
...
verify(bar).doStuff((Foo[]) anyObject());

Answers:


111

从Java 8开始,您可以使用无参数any方法,并且类型参数将由编译器推断:

verify(bar).doStuff(any());

说明

Java 8中的新事物是,表达式的目标类型将用于推断其子表达式的类型参数。在Java 8之前,(大多数时候)仅用于方法的参数用于类型参数推断。

在这种情况下,的参数类型doStuff将是的目标类型any(),并且any()将选择的返回值类型以匹配该参数类型。

此机制主要是在Java 8中添加的,目的是能够编译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。在将返回值intValue传递给之前,运行时将尝试通过调用返回值的方法来取消对返回值的装箱doStuff,并引发异常。


每当这个答案得到好评时,我都会感到惊喜!我猜想自Java 8起,这个问题就不会引起太大的关注,因为该any方法应该可以正常工作。您不会查找仅能正常工作的答案!
Lii

我之所以来到这里,是因为我不知道为什么我的代码无法使用,any()但是可以使用anyBoolean(),您的答案的最后一部分很清楚地说明了这一点。
AdrienW

274

这应该工作

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;

verify(bar).DoStuff(any(Foo[].class));

31
以防万一有人需要在Scala中使用它:verify(bar).DoStuff(any[Array[Foo]])
tolitius

6
我在导入时遇到问题,我在导入中使用了hamcrest的any(),它与模仿者中的那个冲突。
Doppelganger 2014年

4
请看一下API,class参数仅用于强制转换,该方法仍然接受任何类型的对象!site.mockito.org/mockito/docs/current/org/mockito/…。在此案例site.mockito.org/mockito/docs/current/org/mockito/…中使用isA()。
thilko,2015年

1
现在不推荐使用该类,以避免与Hamcrest发生名称冲突。使用org.mockito.ArgumentMatchers
leo9r

12

您可以使用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)


这是正确的答案。使用any(Clazz)是完全错误的。
Surasin Tancharoen

3
@SurasinTancharoen实际上,any(Class)仅仅是isA(Class)的别名(请参阅文档)。因此,这完全没有错。
jmiserez

8

由于我需要在我的最新项目中使用此功能(有一点我们从1.10.19进行了更新),只是为了使用户(已经在使用模仿核心版本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版中删除。

如果您打算进一步阅读,我已经写了一篇关于模拟通配符的文章。


如何在Scala中导入org.mockito.ArgumentMatcher?我尝试导入org.mockito.ArgumentMatcher.any。我收到错误消息`value any不是对象org.mockito.ArgumentMatcher的成员
Manu Chadha

您能告诉我3.0版中的等效功能是什么吗?
Manu Chadha

我们将知道它一旦发布;)
Maciej Kowalski
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.