Mockito: How do you verify the group order of certain groups of method calls?

benjamin picture benjamin · Sep 14, 2012 · Viewed 7k times · Source

I'm using Mockito to verify orders of method calls with the InOrder object. But I am not interested in a total ordering of the calls, only that a certain group of method calls all happen before some other methods are invoked. For example like this

@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();
}

But this test does test too much, since it tests the order of the Foo instances. But I'm only interested in the order of the different methods. In fact I want underTest to not differentiate the instances of Foo, it may have an internal order on them or not, so it does not matter in which order the foos are called. I'd like to keep that as an implementation detail.

But it is important that doThisFirst() has been called on all of the foos before beforeDoingThis() is invoked on any other foo. Is it possible to express that with Mockito? How?

Answer

EdC picture EdC · Sep 14, 2012

Mockito verifies the order across all the mocks that were passed to the inorder function. So if you don't want to verify the order of the foos you need to create two seperate in-orders. i.e.

@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();
}