ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

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

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

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

t
tk_

这应该工作

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

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

以防万一有人在 Scala 中需要它:verify(bar).DoStuff(any[Array[Foo]])
我在导入时遇到了问题,我在导入中使用了来自 hamcrest 的 any(),它与来自 mockito 的那个相撞。
请查看 API,class 参数仅用于强制转换,该方法仍然接受任何类型的对象! site.mockito.org/mockito/docs/current/org/mockito/…。对于这种情况 site.mockito.org/mockito/docs/current/org/mockito/… 使用 isA()。
此类现在已弃用,以避免与 Hamcrest 发生名称冲突。使用 org.mockito.ArgumentMatchers
L
Lii

从 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 返回值,并引发异常。


每次这个答案获得赞成票时,我都会感到惊喜!我猜想这个问题自 Java 8 以来不会引起太多关注,因为 any 方法应该可以正常工作。您不会为正常工作的事情查找答案!
我来到这里是因为我不知道为什么我的代码不能与 any() 一起使用,但可以与 anyBoolean() 一起使用,您答案的最后一部分很好地阐明了这一点。
t
thilko

您可以为此使用 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) 是完全错误的。
@SurasinTancharoen 实际上, any(Class) 只是 isA(Class) 的别名(请参阅文档)。所以这完全没有错。
isA 已弃用
M
Maciej Kowalski

因为我需要将此功能用于我的最新项目(我们曾从 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 的小文章。


如何在 Scala 中导入 org.mockito.ArgumentMatcher?我试过 import org.mockito.ArgumentMatcher.any 我得到错误 `value any is not a member of object org.mockito.ArgumentMatcher
您能否告诉我 3.0 版中的等价物是什么?
一旦它发布,我们就会知道;)