如何验证方法未在对象的依赖项上调用?

例如:

public interface Dependency {
    void someMethod();
}

public class Foo {
    public bar(final Dependency d) {
        ...
    }
}

通过Foo测试:

public class FooTest {
    @Test
    public void dependencyIsNotCalled() {
        final Foo foo = new Foo(...);
        final Dependency dependency = mock(Dependency.class);
        foo.bar(dependency);
        **// verify here that someMethod was not called??**
    }
}

在Mockito.verify方法上使用第二个参数,如下所示:

Mockito.verify(dependency, Mockito.times(0)).someMethod()

更有意义的是:

import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;

// ...

verify(dependency, never()).someMethod();

这个特性的文档在那里§4“验证调用的确切次数/至少x/never”,never javadoc在这里。


作为更一般的模式,我倾向于在测试中使用@After块:

@After
public void after() {
    verifyNoMoreInteractions(<your mock1>, <your mock2>...);
}

然后,测试可以自由地验证应该调用什么。

此外,我发现我经常忘记检查“没有交互”,后来才发现有人在打电话,但不应该打。

因此,我发现这种模式对于捕捉所有未经特别验证的意外呼叫非常有用。


verifyNoMoreInteractions()和verifyZeroInteractions(()方法在内部都具有相同的实现:

public static transient void verifyNoMoreInteractions(Object mocks[])
{
    MOCKITO_CORE.verifyNoMoreInteractions(mocks);
}

public static transient void verifyZeroInteractions(Object mocks[])
{
    MOCKITO_CORE.verifyNoMoreInteractions(mocks);
}

因此,我们可以在mock对象或mock对象数组上使用它们中的任何一个来检查是否没有使用mock对象调用任何方法。


首先:您应该始终导入mockito静态,这样代码将更加可读(直观):

import static org.mockito.Mockito.*;

实际上有很多方法可以实现这一点,但是使用

verify(yourMock, times(0)).someMethod();

方法,当在其他测试中使用它来断言一定数量的执行时,如下所示:

verify(yourMock, times(5)).someMethod();

备选方案包括:

verify(yourMock, never()).someMethod();

或者,当你真的想确保某个被嘲笑的对象实际上根本没有被调用时,你可以使用:

verifyZeroInteractions(yourMock)

请注意:verifyZeroInteractions(对象…模拟)已弃用。自3.0.1版起。现在推荐的方法是:

verifyNoInteractions(yourMock)

作为一个建议,如果您想在语法级别与行为驱动的开发风格保持一致,可以使用BDDMockito:

您可以使用:

then(dependency).should(never()).someMethod();

作为以下内容的等效替代:

verify(dependency, never()).someMethod();