15

我正在使用 Mockito 来验证InOrder对象的方法调用顺序。但是我对调用的总排序不感兴趣,只是在调用其他一些方法之前发生了一组方法调用。例如像这样

@Test
public void testGroupOrder() {
    Foo foo1 = mock(Foo.class);
    Foo foo2 = mock(Foo.class);
    Bar underTest = new Bar();
    underTest.addFoo(foo1);
    underTest.addFoo(foo2);

    underTest.fire()

    InOrder inOrder = inOrder(foo1,foo2);

    inorder.verify(foo1).doThisFirst();
    inorder.verify(foo2).doThisFirst();

    inorder.verify(foo1).beforeDoingThis();
    inorder.verify(foo2).beforeDoingThis();
}

但是这个测试确实测试了太多,因为它测试了Foo实例的顺序。但我只对不同方法的顺序感兴趣。事实上,我不想underTest区分 的实例Foo,它可能有内部顺序或没有,所以调用 foos 的顺序无关紧要。我想将其保留为实现细节。

但重要的是,在任何其他 foo上调用之前doThisFirst()已在所有foo 上调用。可以用 Mockito 来表达吗?如何?beforeDoingThis()

4

2 回答 2

8

Mockito 验证传递给 inorder 函数的所有模拟的顺序。因此,如果您不想验证 foos 的顺序,则需要创建两个单独的顺序。IE

@Test
public void testGroupOrder() {
    Foo foo1 = mock(Foo.class);
    Foo foo2 = mock(Foo.class);
    Bar underTest = new Bar();
    underTest.addFoo(foo1);
    underTest.addFoo(foo2);

    underTest.fire()

    InOrder inOrderFoo1 = inOrder(foo1);
    inOrderFoo1.verify(foo1).doThisFirst();
    inOrderFoo1.verify(foo1).beforeDoingThis();

    InOrder inOrderFoo2 = inOrder(foo2);
    inOrderFoo2.verify(foo2).doThisFirst();
    inOrderFoo2.verify(foo2).beforeDoingThis();
}
于 2012-09-14T09:01:05.003 回答
3

您可以通过实现自己的验证模式来访问内部(感谢这个答案教我,我的代码基于它)。实现并不完整,但你会明白的。

不幸的是,Mockito 没有记录这个接口,他们可能认为它是内部的(所以在未来的版本中它可能不是 100% 稳定的)。

verify(foo1, new DoFirst()).doThisFirst();
verify(foo2, new DoFirst()).doThisFirst();
verify(foo1, new DoSecond()).beforeDoingThis();
verify(foo1, new DoSecond()).beforeDoingThis();

接着

// Set to true when one 
boolean secondHasHappened = false; 

// Inner classes so they can reach the boolean above.
// Gives an error of any DoSecond verification has happened already.
public class DoFirst implements VerificationMode {
   public void verify(VerificationData data) {
      List<Invocation> invocations = data.getAllInvocations()
      InvocationMatcher matcher = data.getWanted();
      Invocation invocation = invocations.get(invocations.size() - 1);
      if (wanted.matches(invocation) && secondHasHappened) throw new MockitoException("...");
   }
}

// Registers no more DoFirst are allowed to match.
public class DoSecond implements VerificationMode {
    public void verify(VerificationData data) {
       List<Invocation> invocations = data.getAllInvocations()
       InvocationMatcher matcher = data.getWanted();
       Invocation invocation = invocations.get(invocations.size() - 1);
       if (!wanted.matches(invocation)) secondHasHappened = true;
    }
}
于 2014-02-11T11:22:43.087 回答