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

问题描述 投票:5回答:3

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

Service类结构就像

public class Service {
    public void serviceA(){...}
    public SomeObject serviceB(){...}
    // can grow in the future
}

Client应该是这样的

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

    public boolean callServiceB(){...}
}

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();
        ????
    }
}

????部分,我想要像verifyOnly(serviceMock).serviceA()说的那​​样“验证serviceMock.serviceA()只被调用一次而没有其他方法来自Service类被称为”。在Mockito或其他一些模拟图书馆中有类似的东西吗?我不想在每种方法中使用verify(serviceMock, never()).serviceXXX(),因为正如我所说,Service类可能会在未来增长,我将不得不在每次测试中添加验证(对我来说不是一项快乐的任务)所以我需要更通用的东西。

提前感谢您的回答。

EDIT #1

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

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

总而言之,possible duplicate并没有解决我的问题。

还有另外一个问题:我正在为另一个团队编写的代码编写测试,而不是自己跟踪TDD进程,所以我的测试应该是额外的防御性,如this articleverifyNoMoreInteractions的mockito文档中引用的那样。我正在测试的方法通常很长,所以我需要检查测试中的方法只调用必要的服务而不是其他服务(因为它们很昂贵,正如我所说)。也许verifyNoMoreInteractions现在已经足够好了,但我希望看到同样的API创建团队的每次测试都不会气馁!

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

java mockito
3个回答
12
投票
verify(serviceMock, times(1)).serviceA();
verifyNoMoreInteractions(serviceMock);

来自qockxswpoi的Mockito的javadoc:

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

也:

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


0
投票

您可以可靠地验证您的服务仅从您指定的方法而不是从任何其他方法调用一次的唯一方法是测试每个方法并声明永远不会调用您的verifyNoMoreInteractions方法。但是你无论如何都要测试其他方法,所以这不应该是那么大的提升......

serviceA

虽然从代码编写的角度来看这是不可取的,但它打开了将您的服务分离成更小,更负责任的块的大门,这样您就可以保证只调用一个特定的服务。从那里开始,您的测试用例和代码保证变得更小,更加铁定。


0
投票

我认为你要找的是Mockito.verify和Mockito.times

// In other test cases...
verify(serviceMock, never()).serviceA();

这里有另一个具有相同问题的线程:

import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; verify(mockObject, atLeast(2)).someMethod("was called at least twice"); verify(mockObject, times(3)).someMethod("was called exactly three times");

© www.soinside.com 2019 - 2024. All rights reserved.