我在我的 JUnit 测试中使用 Mockito。这是一项集成测试,测试整个场景,因此其中有很多断言和 verify(mock)
。
我的问题是,我编写了一些生产代码,执行了一些断言,然后验证模拟对象,这可以正常工作,直到出现相同的模拟调用。以下是简化的代码:
interface I {
void m1();
void m2();
}
// some decorator
class T implements I {
public T(I decorated) {
/*...*/
}
/* ... */
}
public void testInvalid() {
I m = mock(I.class);
T t = new T(m);
t.m1();
assertEquals("m1", t.getLastMethod());
verify(m).m1();
t.m2();
assertEquals("m2", t.getLastMethod());
verify(m).m2();
t.m1();
assertEquals("m1", t.getLastMethod());
verify(m).m1();
// TooManyActualInvocations t.m1(): Wanted 1 time, but was 2 times ...
}
public void testValid() {
I m = mock(I.class);
T t = new T(m);
t.m1();
assertEquals("m1", t.getLastMethod());
t.m2();
assertEquals("m2", t.getLastMethod());
t.m1();
assertEquals("m1", t.getLastMethod());
verify(m, times(2)).m1();
verify(m).m2();
}
一种想法是在最后验证模拟对象,但是假设有一个小的愚蠢实现错误导致方法m1被调用两次,m2被调用一次,但不是我在testInvalid中期望的方式,而是在结束时测试会通过。 我希望我的测试能够尽早失败。我该怎么做?
谢谢。
感谢@Woozy Coder :
没有提到reset也是一个选择,但由于必须在verify和下一个相等的存根调用之间调用它,这使得编写“好看”的正确测试很困难,我认为应该有两种不同的模拟样式:
1.像Mockito一样的"后置条件"模拟 2. "早期"模拟,这将是在verify块后的隐式重置
类似于:
earlyReset(m).after(
new Runnable() {
t.someMethodInvokingTwoStubs();
verify(m).someMethod1();
verify(m).someMethod2();
}
);