2011-04-08 55 views
2

我想編寫一個單元測試(使用JMockit),驗證方法是否按部分順序調用。具體用例是確保某些操作在交易中被調用,但更一般地,我想驗證這樣的事情:在JMockit驗證部分排序的方法調用

  • 方法beginTransaction被調用。
  • 方法operation1operationN以任意順序調用。
  • 方法endTransaction被調用。
  • 方法someOtherOperation在交易之前,期間或之後的某個時間被調用。

Expectations和驗證API似乎無法處理此要求。

如果我有一個@Mocked BusinessObject bo我可以驗證正確的方法調用(以任意順序)與此:

new Verifications() {{ 
    bo.beginTransaction(); 
    bo.endTransaction(); 
    bo.operation1(); 
    bo.operation2(); 
    bo.someOtherOperation(); 
}}; 

可選使其成爲一個FullVerifications檢查有沒有其他的副作用。

要檢查排序約束,我可以做這樣的事情:

new VerificationsInOrder() {{ 
    bo.beginTransaction(); 
    unverifiedInvocations(); 
    bo.endTransaction(); 
}}; 

但這不處理someOtherOperation情況。我無法替換unverifiedInvocationsbo.operation1(); bo.operation2(),因爲這會使合計排序在調用上。業務方法的正確實施可以撥打bo.operation2(); bo.operation1()

如果我讓:

new VerificationsInOrder() {{ 
    unverifiedInvocations(); 
    bo.beginTransaction(); 
    unverifiedInvocations(); 
    bo.endTransaction(); 
    unverifiedInvocations(); 
}}; 

然後我得到一個「沒有驗證的調用左」失敗時someOtherOperation被交易之前調用。嘗試bo.someOtherOperation(); minTimes = 0也不起作用。

因此:在JMockIt中使用Expectations/Verifications API是否有一種乾淨的方法來指定方法調用的部分排序要求?還是我必須使用MockClass和手動跟蹤的調用,一拉

@MockClass(realClass = BusinessObject.class) 
public class MockBO { 
    private boolean op1Called = false; 
    private boolean op2Called = false; 
    private boolean beginCalled = false; 

    @Mock(invocations = 1) 
    public void operation1() { 
     op1Called = true; 
    } 

    @Mock(invocations = 1) 
    public void operation2() { 
     op2Called = true; 
    } 

    @Mock(invocations = 1) 
    public void someOtherOperation() {} 

    @Mock(invocations = 1) 
    public void beginTransaction() { 
     assertFalse(op1Called); 
     assertFalse(op2Called); 
     beginCalled = true; 
    } 

    @Mock(invocations = 1) 
    public void endTransaction() { 
     assertTrue(beginCalled); 
     assertTrue(op1Called); 
     assertTrue(op2Called); 
    } 
} 
+0

覈查,API支持這裏有多個驗證模塊,這將是解決辦法:'someOtherOperation'應該在普通塊*之前*有序進行驗證驗證塊包含對'unverifiedInvocations()'的調用。但是,JMockit目前不支持這種特定的組合。我將嘗試修復0.999.9的版本。 – 2011-05-04 12:02:52

+0

但這是否真正支持部分排序​​的場景?要求bo.operation1()和bo.operation2()必須bo.beginTransaction(後兩者發生)和bo.endTransaction()之前,但交易中的兩個操作可以以任意順序進行。這正是我也需要測試的場景。 – SamStephens 2013-03-21 20:28:02

回答

0

如果你真的需要這樣的測試則:不要用嘲諷的庫,但裏面是國家建立自己的模擬可以簡單地檢查方法的正確順序。 但是調用的測試順序通常是一個不好的標誌。我的建議是:不要測試它,重構。你應該測試你的邏輯和結果,而不是一系列的調用。檢查副作用是否正確(數據庫內容,服務交互等)。如果你測試序列,那麼你的測試基本上是你的生產代碼的精確副本。那麼這種測試的附加價值是什麼?而且這種測試也非常脆弱(如任何重複)。

也許你應該讓你的代碼看起來像這樣:

beginTransaction() 
doTransactionalStuff() 
endTransaction() 
doNonTransactionalStuff()