Mockito在一组其他人之前/之后验证呼叫

时间:2016-04-13 11:05:05

标签: unit-testing mockito verify

如何验证一次通话是在一些其他通话之后(或之前)发生的,而未指定其他通话的订单?

例如:

function finding_exception_model(InfinitiveVerb $infinitiveVerb)
{
    $exceptionmodel = ExceptionModel::NO_EXCEPTIONS;
    if (in_array($infinitiveVerb, IrregularExceptionGroup::$aller)) {
        $exceptionmodel = ExceptionModel::ALLER;
    }
    if (in_array($infinitiveVerb, IrregularExceptionGroup::$avoir_irr)) {
        $exceptionmodel = ExceptionModel::AVOIR_IRR;
    }
    if (in_array($infinitiveVerb, IrregularExceptionGroup::$etre_irr)) {
        $exceptionmodel = ExceptionModel::ETRE_IRR;
    }
    return new ExceptionModel($exceptionmodel);
}

我可能想检查在所有其他交互之后调用class ExceptionModel extends Enum { const NO_EXCEPTIONS = 'no exceptions'; const ALLER = 'aller'; const AVOIR_IRR = 'avoir_irr'; const ETRE_IRR = 'etre_irr'; } 。但我不想将它们限制在特定的序列上。

2 个答案:

答案 0 :(得分:1)

可能有更好的选择(我会等待其他答案),但有一种选择是定义三个不同的InOrder,每个方法调用一次(objA,objB,objC)和事务,以及然后独立验证所有InOrder。

这样的事情(只是一个例子):

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

希望有所帮助

答案 1 :(得分:0)

可能不是您正在寻找的答案,但有时难以测试代码意味着是时候重构了。将三个与顺序无关的方法调用的序列作为单个方法myClass.abcMethods()提取,然后在您的SUT上使用Spy,只需InOrder验证myClass.abcMethods(),然后transaction.commit()