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

时间:2017-07-13 20:27:18

标签: java mockito

我正在一个项目中工作,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类可能会在将来增长,我将不得不在每次测试中添加验证(不是一项快乐的任务)对我来说)所以我需要一些更通用的东西。

提前感谢您的回答。

编辑#1

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

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

为了改善,possible duplicate没有解决我的问题。

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

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

3 个答案:

答案 0 :(得分:12)

AppDelegate

来自retention policy的Mockito的javadoc:

  

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

此外:

  

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

答案 1 :(得分:0)

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

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

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

答案 2 :(得分:0)

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

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");

这是另一个有相同问题的主题:

Mockito: How to verify a method was called only once with exact parameters ignoring calls to other methods?