使用verifyNoMoreInteractions()强制进行未来测试更新的有效性

时间:2018-04-11 10:56:31

标签: java unit-testing junit mockito

我的一位同事在JUnit测试中使用Mockito.verifyNoMoreInteractions()来确保测试代码未来可能的更改将使测试失败,并迫使未来的开发人员在更改测试代码时更新测试。

伪代码示例:

class TestedClass {
  DependencyA dependency1;
  DependencyB dependency2;
  DependencyC dependency3;

  public void testedMethod(SomeClass a) {
    if(a == null) {
        return;
    }

    //in real code there are over a dozen of such calls, example code 
    //is simplified for clarity
    dependency1.doA();
    dependency2.doB();
    dependency3.doC();
    //future developer might add dependency3.doOtherC(); here
  }
}

class TestedClassTest {
    @Mock DependencyA dependencyAMock;
    @Mock DependencyB dependencyBMock;
    @Mock DependencyC dependencyCMock;
    @Mock SomeObject someObejctMock;

    TestedClass testedObject;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);

        testedObject = new TestedObject(dependencyAMock, dependencyBMock, dependencyCMock);
    }

    @Test
    public void shouldCallDependencyMethods_OnTestedMethod_GivenSomeClassNotNull() {
        testedObject.testedMethod(someObjectMock);

        then(dependencyAMock).should().doA();
        then(dependencyBMock).should().doB();
        then(dependencyCMock).should().doC();

        //is this check acceptable ?
        Mockito.verifyNoMoreInteractions(dependencyAMock, dependencyBMock, dependencyCMock);
    }
}

Mockito文档警告不要这样做(https://static.javadoc.io/org.mockito/mockito-core/2.18.0/org/mockito/Mockito.html#finding_redundant_invocations):

A word of warning: Some users who did a lot of classic, expect-run-verify mocking tend to use verifyNoMoreInteractions() very often, even in every test method. verifyNoMoreInteractions() is not recommended to use in every test method. verifyNoMoreInteractions() is a handy assertion from the interaction testing toolkit. Use it only when it's relevant. Abusing it leads to overspecified, less maintainable tests

我们谈到了这一点,他认为,如果测试代码将来发生变化(在示例代码中添加新的依赖方法调用,例如dependency3.doOtherC(),理论上可能会发生,但不一定必须),引入此类更改的开发人员可能不会记得使用相关检查更新测试(实际上已经在我们的项目中发生了几次)。通过使用verifyNoMoreInteractions()检测此类新更改而导致测试失败将迫使他们更新测试。

由于我负责代码审查,因此我必须对此类解决方案采取立场。虽然Mockito文件明显反对,但我必须承认,在这种特定情况下,我看到了这种“防御性”验证的目的。

在这种情况下这种解决方案是否可以接受?有没有其他方法可以确保更新测试?

1 个答案:

答案 0 :(得分:0)

  • TestedClass testedObject;应使用@InjectMock进行注释,并命名为cut(Class Unter Test)。
  • 您可以根据需要使用verifyNoMoreInteractions(),但是 就像所有“扩张”方法一样,如果可能的话,你应该避免它。所以 如果函数不使用它的类的任何依赖,你不需要调用verifyNo.. - 但如果你不确定这是否会永远这样说,你可以/可以。

TL;博士;使用它 - 或不是:就像宗教或政治一样 - 每个人都喜欢这样做(安全使用它但经常超载)