我正在使用 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 isreset()
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/