2010-12-09 56 views
2

mockito有可能根據模擬是否實際用於被測單元來驗證模擬方法是否被調用?Mockito有工廠條件驗證

對於一個簡單的例子,我提供了一個模擬工廠(FooFactory)給我的被測單元,當調用Foo.create()時,它返回一個模擬(Foo),供某些方法在單元被測。我如何驗證Foo.method()僅在被測單元調用Foo.create()時才被調用?

我預想的代碼會是這個樣子:

@Before 
public void init() { 
    Foo mockFoo = mock(Foo.class); 
    when(fooFactory.create()).thenReturn(mockFoo); 
    test = new UnitUnderTest(fooFactory); 
} 

@Test 
... may or may not create a foo ... 

@After 
public void cleanup() { 
    if (verify(fooFactory).create()) { // Here's the 'conditional verification' 
    Foo mockFoo = fooFactory.create(); 
    verify(mockFoo).close(); 
    } 
} 

對於一個小更具體的例子,我的工廠返回,我要確保關閉Reader對象,而不是在每一個方法該類實際上構造了一個Reader。我明顯可以將驗證添加到每個我知道需要讀取器的測試中,但這看起來像是很多重複的工作。

回答

1

您確定要編寫此測試嗎?

我可以看到兩個解決方案:

1)你真的要確保資源被創建和關閉,所以要儘量寫一個測試,在這裏你可以驗證這兩種方法調用。

2)你想確保每當資源被打開時,它也被關閉。這可以作爲產品代碼中的斷言來實現...如果你真的想繼續使用你的方法,你可以捕獲第一次驗證拋出的異常,如果沒有調用create()方法。在捕捉中你只是回來。

此外,您不應該在清理中進行驗證,而應該在實際測試方法中進行驗證。

+0

+1。您可以爲這兩種情況創建單獨的單元測試(例如,testWasInteraction,testNoInteraction),並且在清理方法中沒有任何其他驗證。底線 - 如果你想要這個驗證,寫出特定的單元測試。最後,如果會出現一個bug,你會希望看到一個測試失敗,而不是每個測試用例使用這種方法的多個失敗。 – 2010-12-10 00:07:37

0

老實說,聽起來你的測試太複雜了。這是我對許多項目和大量單元測試的經驗,處理事情的最佳方式是確保每個測試只測試一件事情。您可以擁有儘可能多的斷言,但應該調用一種方法並測試一種情況。任何事情和測試變得太複雜。另外,當其他開發人員在進一步開發應用程序時,很難在稍後階段拿起測試。

所以我建議把測試分成多個測試,每個測試一個測試,然後看看你是否仍然需要測試。