Stubbing 一个带有副作用的 void 方法

Stubbing a void method with side effects

如何替换存根的void方法的方法体?

像这样:

interface Foo {
    void foo(Integer j);
}

(...)

Foo mockFoo = mock(Foo.class);

Answer<Void> ans = invocation -> {
            Object[] args = invocation.getArguments();
            System.out.println("called with arguments: " + Arrays.toString(args));
            return null;
        };

when(mockFoo.foo(any())).thenAnswer(ans);

(...)

mockFoo.foo(5) // Should print out "called with arguments: [5]"

能够访问参数并能够执行一些使用这些参数的代码非常重要。

我们尝试了 doAnswer(ans).when(mockFoo).foo(any());,但它似乎在设置模拟时执行了几次 ans lambda 的主体,并且由于 .when(mockFoo).foo(any()) 调用。

如此有效:

Foo mockFoo = mock(Foo.class)
// mockFoo is an instance of a Foo$MockitoMock

Foo o = doAnswer(ans).when(mockFoo);
// mockFoo just became null at this point..?!
o.foo(any());

P.S。我们正在使用 VertxUnitRunner 进行 运行 测试,但问题仍然存在于 MockitoJUnitRunner 中。

已在评论中解决:

You were right. In my actual test I was supplying any() as parameter for an int, which seems to have been the cause. Replacing it with anyInt() fixed the problem.

这很难警告,因为异常来自 Mockito 的默认 null 值(由于擦除而必需)被自动拆箱(由于 Java 5+ 语义而必需),这是在 Mockito 的控制之外并且在 Mockito 知道您的测试试图调用哪个方法签名之前。这也不是Mockito异常,甚至不是Mockito故意调用的异常,所以报错信息很难用建议修改。

对于原始值中 Mockito 匹配器的所有使用,请使用适当的原始值:anyIntintThat,等等。