Mockito验证只调用了一个预期的方法

Alv*_*aza 12 java mockito

我正在一个项目中工作,有一个Service类和一个Client充当外观的东西(不知道它是否是设计模式世界中的正确术语,但我会尽力使自己清楚).Service方法可能非常昂贵,因为它们可能与一个或多个数据库进行通信,长检查等等,因此每个Client方法都应该调用一个且只能调用一个Service方法.

Service 类结构是这样的

public class Service {
    public void serviceA(){...}
    public SomeObject serviceB(){...}
    // can grow in the future
}
Run Code Online (Sandbox Code Playgroud)

而且Client应该是这样的

public class Client {
    private Service myService; // Injected somehow
    public void callServiceA() {
        // some preparation
        myService.serviceA();
        // something else
    }

    public boolean callServiceB(){...}
}
Run Code Online (Sandbox Code Playgroud)

在测试课中,Client我希望有类似的东西

public class ClientTest{
    private Client client; // Injected or instantiated in @Before method
    private Service serviceMock = mock(Service.class);

    @Test
    public void callServiceA_onlyCallsServiceA() {
        client.callServiceA();
        ????
    }
}
Run Code Online (Sandbox Code Playgroud)

在本????节中,我想要verifyOnly(serviceMock).serviceA()"验证serviceMock.serviceA()只调用一次,并且没有Service调用类中的其他方法".在Mockito或其他一些模拟图书馆中有类似的东西吗?我不希望使用verify(serviceMock, never()).serviceXXX()的每一个方法,因为,正如我所说,Service类可能在未来的成长,我将不得不增加验证每一个测试(不是为我一个幸福的任务),所以我需要更多的东西一般.

提前感谢您的回答.

编辑#1

这篇文章与可能的重复之间的区别在于答案增加了锅炉板代码,这在我的案例中是不可取的,因为它是一个非常大的项目,我必须添加尽可能少的代码.

此外,即使不鼓励每次测试,也不需要额外的锅炉板代码,verifyNoMoreInteractions可能是一个不错的选择.

为了sumarize,可能的重复并没有解决我的问题.

还有一个问题:我正在写另一队取得测试代码,而不是遵循TDD proccess自己,所以我的测试应该是额外的防御性,如在规定这篇文章的文档的Mockito在引述verifyNoMoreInteractions.我正在测试的方法通常很长,所以我需要检查测试中的方法只调用必要的服务而不是其他服务(因为它们很昂贵,正如我所说).也许verifyNoMoreInteractions现在已经足够好但是我希望看到同一个API创建团队的每次测试都不会气馁!

希望这有助于澄清我的观点和问题.最好的祝福.

Mat*_*aga 17

verify(serviceMock, times(1)).serviceA();
verifyNoMoreInteractions(serviceMock);
Run Code Online (Sandbox Code Playgroud)

来自Mockito的javadoc上的verifyNoMoreInteractions:

验证模拟后,您可以使用此方法 - 以确保您的模拟没有调用任何其他内容.

也:

警告:有些用户经常做很多经典的,期望运行验证的模拟,往往会经常使用verifyNoMoreInteractions(),即使在每种测试方法中也是如此.建议不要在每个测试方法中使用verifyNoMoreInteractions().verifyNoMoreInteractions()是交互测试工具包中的一个方便的断言.仅在相关时使用它.滥用它会导致过度指定,不易维护的测试.

  • 如果您只检查一次调用,则不需要“times(1)”。 (2认同)