2012-08-24 54 views
2

比方說,我有兩個方法,其中一個是基本上與額外處理的只是一點點的其它方法的包裝:在這種情況下部分嘲諷有什麼問題?

public class ItemRepositoryImpl implements ItemRepository { 

    ... 

    @Override 
    public void delete(UUID itemID) { 

     Item item = findOne(itemID); 
     delete(item); 
    } 

    @Override 
    public void delete(Item item) { 

     // Do a bunch of stuff that needs a lot of tests run on it, like 
     // deleting from multiple data sources etc 
     ... 
    } 
} 

什麼是錯編寫單元測試刪除(UUID)方法部分嘲諷ItemRepositoryImpl,並檢查該刪除(UUID)最終調用delete(Item)?如果我這樣做了,我不必爲每個刪除方法寫一堆重複的測試!

在的Mockito,我可以實現這樣的測試用這樣的間諜:

ItemRepository spyRepo = spy(repository);  // Create the spy 
when(spyRepo.findOne(itemID)).thenReturn(item); // Stub the findOne method 
doNothing().when(spyRepo).delete(item);   // Stub the delete(Item) method 
spyRepo.delete(itemID);       // Call the method under test 

// Verify that the delete(Item) method was called 
verify(spyRepo).delete(item); 

然而,的Mockito文檔強烈反對使用這種類型的偏嘲諷的,基本上說,它應該只用於在臨時遺留代碼和第三方API上。什麼會更好的解決方案?

+0

雖然它真的是一堆重複測試嗎?我想象一下'delete(UUID)'的兩個測試 - 其中一個項目被找到,另一個找不到項目。在delete(Item)'的測試中測試調用的'delete(Item)'部分中的任何詳細處理。 –

回答

1

如果你正在做一個純粹的單元測試,並且你的測試單元是一種方法,那麼我會說你在這裏嘲笑的東西沒有錯。有人會認爲單元測試應該採取更加黑盒子的方法,並且通過模擬方法調用,測試對測試方法的實現知道太多。

如果被測試的單元是類而不是方法,那麼你可以簡單地將對其他類的調用模擬。

單元測試總是存在爭議。這裏有一篇關於這個主題的文章,與你的問題非常相關:http://martinfowler.com/articles/mocksArentStubs.html