Mockito:存根长调用栈

时间:2018-03-30 20:05:44

标签: java unit-testing ide

我有一个服务,其中注入了许多其他对象(应该被模拟),我需要在某些方法上编写单元测试。问题是,此方法在此服务中使用了许多其他方法,因此我需要编写许多行,如when(someMock.someMethod()).thenReturn(someValue)。我不得不写上面的12行,我手动复制粘贴了方法I测试使用的5种方法。

手动跟踪接下来要调用的方法非常麻烦,我想知道是否有三个IDE插件,我可以为特定测试用例指定执行的开始和结束,并显示需要模拟的对象?

我无法单独测试每个方法,因为调用堆栈中的大多数方法都是私有的,我需要测试调用堆栈中最后一个方法抛出的异常。

1 个答案:

答案 0 :(得分:0)

首先,如果你需要模仿这么多东西,这是明确的信号,你需要重构。所以我假设你目前无法重构该代码。

我不认为有插件可以做到这一点。这样的插件需要执行代码来计算我们应该被模拟的所有依赖项,因为一些需要模拟的东西在运行时才变得可见。

如果我使用这样的遗留代码并且现在无法重构,我会使用测试本身来帮助我使用Mockito找到所有类似的模拟:

使用@InjectMocks

配置automatic mocks injection
@InjectMocks private MyService sut;

创建测试:

@Test
public void testSomething() {
    sut.doSomething();

    // assert something
}   

现在的目标是通过添加必需的模拟使您的断言失败。只需运行测试。在调用某些mock时,它很可能会失败NullPointerException

在测试方法之前添加该模拟(假设MyService使用基于注入的字段或setter):

@Mock private SomeDependency someDependency;

@Test
public void testSomething() {
    sut.doSomething();

    // assert something
}   

重新运行测试。如果刚刚调用了SomeDepenency并且它返回的默认值足够,那么您将点击下一个未模拟的依赖关系并以相同的方式处理它。

如果需要从模拟调用中返回一些特定值,则在测试中添加模拟的配置:

when(someMock.someMethod()).thenReturn(someValue)

你重复这个,直到你得到你最初创建的断言失败。

然后我将所有定义的模拟移动到测试类的开头。