java - Mockito,验证函数被调用 0 次

标签 java unit-testing mockito

我正在使用 Mockito写我的测试用例。我有一个简单的类,其中包含一个我有兴趣测试的函数 countPerson(boolean):

public class School {
    //School is a singleton class.

    public void countPerson(boolean includeTeacher) {
        if (includeTeacher) {
            countIncludeTeacher();
            return;
        }
        countOnlyStudents();
    }

    public void countIncludeTeacher() {...}
    public void countOnlyStudents() {...}
}

在我的单元测试中,我想测试 countPerson(boolean) 方法:

@Test 
public void testCountPerson() {    
    School mSchool = School.getInstance();
    School spySchool = Mockito.spy(mSchool);
    spySchool.countPerson(true);

    //Verify the function countIncludeTeacher is invoked once
    verify(spySchool).countIncludeTeacher();
    //Until here things are working well.

    spySchool.countPerson(false);
    //ERROR HERE when I try to verify the function has 0 times invoke
    verify(spySchool, times(0)).countIncludeTeacher();      
}

我有以下错误:

org.mockito.exceptions.verification.NeverWantedButInvoked: school.countIncludeTeacher(); Never wanted here: (SchoolTest.java 20)

为什么0次验证不起作用?

最佳答案

实际上,问题在于每个 verify 调用都是在同一个 spySchool 实例上进行的。让我解释一下:

@Test 
public void testCountPerson() {    
    School mSchool = School.getInstance();
    School spySchool = Mockito.spy(mSchool); // a spy is created here, Mockito is listening in.
    spySchool.countPerson(true); // real method is invoked
    verify(spySchool).countIncludeTeacher(); // our spy identified that countIncludeTeacher was called

    spySchool.countPerson(false); // real method is invoked
    verify(spySchool, times(0)).countIncludeTeacher(); // our spy still identified that countIncludeTeacher was called, before it was called before
}

问题是,在最新的verify中,它失败了,因为之前在 spy 上调用了countIncludeTeacher方法并且调用的方法没有注销。

您可以使用 verifyNoMoreInteractions 来做到这一点,它验证对象没有更多的交互。你也可以 reset对象。

但请注意,这确实不推荐,引用 Mockito Javadoc:

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. You can find further reading here.

Smart Mockito users hardly use this feature because they know it could be a sign of poor tests. Normally, you don't need to reset your mocks, just create new mocks for each test method.

Instead of reset() please consider writing simple, small and focused test methods over lengthy, over-specified tests. First potential code smell is reset() in the middle of the test method. This probably means you're testing too much. Follow the whisper of your test methods: "Please keep us small & focused on single behavior".

我肯定会建议您将这个测试分成两部分:一个用于 true 情况,一个用于 false 情况。

关于java - Mockito,验证函数被调用 0 次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33671798/

相关文章:

java - Android SimpleDateFormat.format 给出错误的数字量,例如 Minute "0040"随机

java - 根据值更改不同的变量以实现高效的代码重用

java - 在单元测试中等待 Platform.RunLater

reactjs - 如何从 @react-native-firebase/auth 模拟身份验证

visual-studio-2010 - 是否可以使用 Resharper GUI 可视化参数化 NUnit 测试?

使用 jar 运行时,Java 不遵循 -cp 选项的类路径规范

java - 使用 Maven 运行常规测试

java - 如何验证使用 mockito 调用公共(public)类的静态方法?

spring-boot - 无法使用 Mockito 模拟 Spring-Data-JPA 存储库

mocking - 我可以模拟带有 juni5 和 mockito 或 easymock 的静态方法吗?