2011-07-05 71 views
2

我正在學習Mockito。在開始使用模擬對象之前,我不得不說更像集成測試一些單元測試,所以我有這樣一個setUpBeforeClass(試驗班):Junit/Mockito:選擇運行模擬測試或集成測試

@BeforeClass 
public static void setUpBeforeClass() throws Exception { 
    instance = new UserDataAccess(); 
    instance.setDb(new MyDb()); 
} 

現在用模擬對象是相似的很多,但是設置略微複雜一些:

@BeforeClass 
public static void setupBeforeClass throws Exception { 
    instance = new UserDataAccess(); 
    MyDb myDb = mock(MyDb.class); 
    when(...).thenReturn(...); 
    ... 
    instance.setDb(myDb); 
} 

而且我有一個測試套件,用於在運行測試之前加載DB在一個衆所周知的狀態,這是由稱爲第一類測試完成該套件。

我在想,我不應該扔掉集成測試,所以我正在考慮將測試套件分成一個UnitTestSuite和一個IntegrationTestSuite。事實上,模擬測試並沒有測試所有的東西,例如他們不測試查詢是否正確。

此外,這兩個套件之間的唯一區別將是初始DB重置和setUpBeforeClass()代碼。複製和更改所有測試類只是爲了更改方法是浪費。初始DB重置很容易跳過,我只是沒有在單元測試套件中包含db重置測試類。

要拆分單元和集成測試你有什麼建議?擴展所有原始類以覆蓋靜態方法,然後在套件中包含正確的類?

還是其他方法?你是怎麼做的,或者你會怎麼做?

回答

9

一定要記住,單元測試(使用mock)背後的想法是戳和單個類的所有黑暗角落。他們的目的是確保班級按照您所想的所有類型的輸入行爲。這就是爲什麼我們使用mock做這件事的原因,因爲我們可以編程這些mock來做各種可能難以再現的事情,如果這個類與應用程序的其他部分聯繫在一起的話。

另一方面,集成有不同的重點。這是關於確保你所有的課程一起工作,以產生預期的結果。所以在編碼時要記住這一點。這是你以後的大局。你不需要擔心模糊單個類的邊緣情況,因爲這是模擬單元測試的工作。但是像數據庫狀態這樣的事情正是爲什麼集成測試很重要。

我也同意@stivlo關於在內存數據庫工作中使用像HSQL這樣的產品。它們既可以加速集成測試,又有助於確保測試的已知起點。

我會建議保持您的單元測試和集成測試在單獨的目錄或至少單獨命名匹配的軟件包。簡單,因爲它可以幫助你記住你正在處理的事情。

還要小心測試蠕變。 IE瀏覽器。實例化大量應用程序類的單元測試,實際上應該被轉移到集成測試中,並且集成測試正在爲一個類做很多詳細的變體樣式測試 - 單元測試的候選。特別是對於最後一個,如果存在不應該存在的集成測試,則可以修剪大量時間。

最後,像任何代碼一樣,測試代碼不時需要一點愛和關注。因此請留意重構機會。話雖如此,我還看到測試代碼已變得難以使用,因爲它太泛化且過度設計。記住測試代碼不是生產代碼,所以在大多數情況下,清晰度比工程更重要。這是一個平衡,你會通過經驗。

+0

Upvoted爲關於'測試蠕變'的段落。集成測試和單元測試通常在使用模擬方面有所不同,單元測試涵蓋單一類合同,集成測試覆蓋(部分)用例與整個系統。 –

+0

謝謝Derek,所以在實踐中你說的是,運行與集成和單元測試相同的測試可能不是一個好主意,只是重複一種方法,因爲我會錯過測試的不同重點,而我或許過度設計了測試,所以我不妨將其與一些代碼重複進行交換。它是否正確? – stivlo

+0

是的,差不多。我確信有些人會不同意代碼重複,但如果有助於保持清晰的話,我不介意有點重複。它非常依賴於你的測試。如果你無法花費30分鐘時間來閱讀和理解它們,那麼它們就太複雜了。另一方面,如果在包含單元測試的類中看到4次或5次相同的設置,則可能將其重構爲抽象或setup()方法。正如我所說,這是一個基於代碼的個人通話。最好的指南是KISS。 – drekka

0

我建議使用內存數據庫進行集成測試,而不是模擬對象。

對於單元測試,我假設你使用數據庫作爲存根提供一些數據到測試中,並作爲模擬測試時調用類似saveMyDomainObject()的東西。在第一種情況下,您只能嘲笑您對特定測試實際需要的內容,而不是整個數據庫設置。對於第二種情況,您應該使用Mockito的validate來檢查預期行爲是否正確。

+0

實際上,我正在使用僅測試db模式進行集成測試,我在每次測試運行時重新加載(真正的db包含數百萬條記錄,但我在測試數據庫中只有幾千個,因此它不會沒多久)。我正在使用,或者更好地開始使用模擬對象進行單元測試。 使用內存數據庫的優勢可能會更快一些,但這意味着需要額外的努力來消除SQL不兼容問題,並且這意味着我不再在真實平臺上進行測試,因此它可能工作得很好在內存數據庫中,並在SQL差異的實際平臺上失敗。 – stivlo