我已经接受了一系列测试来开发一个简单的游戏,我已经到了Mockito的InOrder.verify()
产生错误的地步。
订单验证失败。需要但未调用:第x行的jumpListener.jumpPerformed(…)。在以下交互之后的任何位置都需要:第y行的walkListener.walkPerformed
我得到的代码看起来与下面的代码类似,其中相关函数performWalk(int x)
和performJump(int y)
都包含if/else逻辑中的其他函数调用,在walkListeners.get(0).walkPerformed(x);
和jumpListeners.get(0).jumpPerformed(y);
之前和之后。在谈到这一部分之前,我从未听说过Mockito,大多数问题似乎都是由那些制作测试的人提出的,而不是使用测试的人。所以我的问题是,inOrder.verify()
对函数调用到底要求什么?
order.verify(walkListener).walkPerformed(5);
order.verify(jumpListener).jumpPerformed(2);
这两个语句之间是否会发生其他函数调用,比如布尔函数检查参数值间隔?
public interface WalkListener extends EventListener {
public void walkPerformed(int x);
}
public interface JumpListener extends EventListener {
public void jumpPerformed(int y);
}
public class Game {
private Vector<WalkListener> walkListeners;
private Vector<JumpListener> jumpListeners;
public void addWalkListener(WalkListener listener) { ... }
public void addJumpListener(JumpListener listener) { ... }
public void performWalk(int x) {
...
walkListeners.get(0).walkPerformed(x);
...
}
public void performJump(int y) {
...
jumpListeners.get(0).jumpPerformed(y);
...
}
private class Walk implements WalkListener { ... }
private class Jump implements JumpListener { ... }
}
public class GameTest {
@Test
public void finalTest() {
Game game = new Game();
WalkListener walkListener = mock(WalkListener.class)
JumpListener jumpListener = mock(JumpListener.class)
game.addWalkListener(walkListener);
game.addJumpListener(jumpListener);
game.performWalk(5);
game.performJump(2);
InOrder order = inOrder(walkListener, jumpListener);
order.verify(walkListener).walkPerformed(5);
order.verify(jumpListener).jumpPerformed(2);
}
}
所以这是相关的位:
InOrder order = inOrder(walkListener, jumpListener);
order.verify(walkListener).walkPerformed(5);
order.verify(jumpListener).jumpPerformed(2);
它验证
- jumpListener是在walkListener之后调用的(在这种情况下,您失败了,因为您显然根本没有调用jump Listener)
- 使用参数
5
调用walkListener.walkPerformed(),并且 - 使用参数
2
调用jumpListener.jumpPerformed()
这两个语句之间是否会发生其他函数调用,比如布尔函数检查参数值间隔?
当然。
参见示例:
class Foo {
public void foo() {}
public void bar() {}
public void baz() {}
}
@Test
public void testFoo() {
Foo mock = mock(Foo.class);
mock.foo(); //1st
mock.bar(); //2nd
mock.baz(); //3rd
InOrder inOrder = inOrder(mock);
inOrder.verify(mock).foo(); //1st
inOrder.verify(mock).baz(); //3rd (last method)
//passes because there are no more interactions after last method:
inOrder.verifyNoMoreInteractions();
}
测试通过,因为在baz()
调用之后没有更多的方法调用。bar()
调用介于两者之间并不重要,因为这不是验证的一部分。
两个类别也是如此:
class Foo {
public void foo() {}
public void bar() {}
}
class Bar {
public void foo() {}
}
@Test
public void testFoo() {
Foo mock = mock(Foo.class);
Bar mock2 = mock(Bar.class);
mock.foo(); //1st
mock.bar(); //2nd
mock2.foo(); //3rd
InOrder inOrder = inOrder(mock, mock2);
inOrder.verify(mock).foo(); //1st
inOrder.verify(mock2).foo(); //3rd (last method)
//passes because there are no more interactions after last method:
inOrder.verifyNoMoreInteractions();
}
测试再次通过,因为第二个方法调用不是验证的一部分。
如果您希望测试在未指定的方法调用上失败,则需要在测试结束时添加例如Mockito.verifyNoMoreInteractions(mock);
。