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

问题描述 投票:0回答:5

我有一个接口,其方法需要一个

Foo
数组:

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

我正在使用 Mockito 模拟这个接口,我想断言

doStuff()
被调用,但我不想验证传递了什么参数 - “不关心”。

如何使用泛型方法

any()
而不是
anyObject()
来编写以下代码?

IBar bar = mock(IBar.class);
...
verify(bar).doStuff((Foo[]) anyObject());
java unit-testing mocking mockito
5个回答
298
投票

这应该有效

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

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

149
投票

从 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
方法来取消装箱,并引发异常。


16
投票

因为我需要在我的最新项目中使用此功能(一度我们从 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 指出:

使用

org.mockito.ArgumentMatchers
。该类现已弃用,以便 避免与 Hamcrest 发生名称冲突 *
org.hamcrest.Matchers
班级。这个类可能会在 3.0 版本中被删除。

如果您想进一步阅读,我已经写了一篇关于 mockito 通配符的小文章。


13
投票

您可以使用

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)


0
投票

在最新版本的 Mockito 中,您可以使用任何(Foo.class)

© www.soinside.com 2019 - 2024. All rights reserved.