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

2022-08-31 05:58:19

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

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

我使用Mockito嘲笑这个接口,我想断言它被调用,但我不想验证传递了什么参数 - “不在乎”。doStuff()

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

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

答案 1

这应该有效

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

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

答案 2

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

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

解释

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

在这种情况下,参数类型 将是 的目标类型,并且 将选择 返回值类型 来匹配该参数类型。doStuffany()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

问题是编译器将推断为 返回值类型 。Mockito 不会意识到这一点(由于类型擦除),并返回引用类型的默认值,即 。运行时将尝试在将 null 返回值传递给 之前调用该返回值的方法,从而取消其装箱,并引发异常。Integerany()nullintValuedoStuff


推荐