Victor Basso
Victor Basso

Reputation: 5796

Mockito verify call before/after a group of others

How to verify that one call happens after (or before) a number of other calls, without specifying an order for the others?

E.g.:

objA.method1();
objB.method2();
objC.method3();
transaction.commmit();

I might want to check that commit is called after all those other interactions. But I don't want to constraint them on a specific sequence.

Upvotes: 2

Views: 954

Answers (2)

Kevin Welker
Kevin Welker

Reputation: 7937

Possibly not the answer you are looking for, but sometimes hard to test code means it's time to refactor. Extract the sequence of three order-independent method calls as a single method myClass.abcMethods(), and then using a Spy on your SUT simply do an InOrder verify of myClass.abcMethods() and then transaction.commit()

Upvotes: 0

troig
troig

Reputation: 7212

Probably there are better options (I'll be waiting for other answers), but one choice is defining three different InOrder, one per each method call (objA, objB, objC) and transaction, and then verify all InOrder independently.

Something like this (is just an example):

class ObjA {
  void method1() {}
}

class ObjB {
  void method2() {}
}

class ObjC {
  void method3() {}
}

class Transacction {
  void commit() {};
}

class ClassToTest {
  private ObjA objA;
  private ObjB objB;
  private ObjC objC;
  Transacction transaction;

  ClassToTest(ObjA objA, ObjB objB, ObjC objC, Transacction transaction) {
     this.objA = objA;
     this.objB = objB;
     this.objC = objC;
     this.transaction = transaction;
  }

  void method() {
     objA.method1();
     objC.method3();
     objB.method2();

     transaction.commit();
  }
}

Test method:

@Test
public void testMethod() throws Exception {
   ObjA objA = mock(ObjA.class);
   ObjB objB = mock(ObjB.class);
   ObjC objC = mock(ObjC.class);
   Transacction transaction = mock(Transacction.class);

   // Create a InOrder per each call and transaction
   InOrder inOrderObjA = inOrder(objA, transaction);
   InOrder inOrderObjB = inOrder(objB, transaction);
   InOrder inOrderObjC = inOrder(objC, transaction);

   ClassToTest classToTest = new ClassToTest(objA, objB, objC, transaction);
   classToTest.method();

   // Verify transaction.commit() is executed after objA.method1()
   inOrderObjA.verify(objA).method1();
   inOrderObjA.verify(transaction).commit();

   // Verify transaction.commit() is executed after objB.method2()
   inOrderObjB.verify(objB).method2();
   inOrderObjB.verify(transaction).commit();

   // Verify transaction.commit() is executed after objC.method3()
   inOrderObjC.verify(objC).method3();
   inOrderObjC.verify(transaction).commit();
}    

Hope it helps

Upvotes: 1

Related Questions