2011-04-06 179 views
3

首先,我不得不說,我是新來的嘲弄。所以也許我錯過了一個觀點。TDD和嘲諷

我也剛開始習慣TDD方法。

因此,在我的實際項目中,我正在業務層的一個類中工作,而數據層尚未部署。我想,這將是開始嘲笑的好時機。我正在使用Rhino Mocks,但在寫類之前,我需要了解一個類的實現細節。

Rhino Mocks會檢查是否實際調用預期調用的方法。所以我經常需要知道被測方法首先調用哪個模擬方法,即使它們可以以任何順序調用。正因爲如此,我在測試它們之前經常編寫複雜的方法,因爲那樣我就知道調用方法的順序。

簡單的例子:

public void CreateAandB(bool arg1, bool arg2) { 
    if(arg1) 
     daoA.Create(); 
    else throw new exception; 
    if(arg2) 
     daoB.Create(); 
    else throw new exception; 
} 

,如果我想測試這種方法的錯誤處理,我必須知道哪些方法被首先被調用。但我不想在第一次編寫測試時對實現細節感到迷惑。

我錯過了什麼嗎?

回答

4

您有2個選擇。如果該方法會導致您的課程發生某些變化,您可以測試方法的結果。所以你可以打電話CreateAandB(true,false),然後調用其他方法來查看是否創建了正確的東西。在這種情況下,你的模擬對象可能只是提供一些數據的存根。

如果doaAdoaB是注入到您的類中的實際創建數據庫或類似的對象,而您無法驗證測試結果,那麼您想測試與它們的交互,在這種情況下,您創建模擬並設置期望值,然後調用該方法並驗證滿足期望值。在這種情況下,你的模擬對象將會嘲笑並且會驗證預期的行爲。

是要測試的實施細節,但你的,如果你的方法正確使用它的依賴,這是你想要的測試,不如何它使用它們,這是詳細測試的細節你是不是真正感興趣。

編輯

IDao daoA = MockRepository.GenerateMock<IDao>(); //create mock 
daoA.Expect(dao=>dao.Create); //set expectation 

... 

daoA.VerifyExpectations(); //check that the Create method was called 

可以保證期望按照一定的順序發生,但不使用AAA語法,我相信(source from 2009,可能已經改變,編輯see here爲可能工作的選項),但似乎有人開發了一種方法,可能會允許這here。我從來沒有使用過,無法驗證它。

至於需要知道哪種方法首次被這樣你就可以驗證你有兩個選擇除外:

  • 有不同的消息在您的異常,並檢查,以確定哪些異常發生。
  • 除了期待異常之外,還需要調用daoA。如果你沒有接到對daoA的調用,那麼測試失敗,因爲例外必須是第一個。
+0

daoA和daoB正在注入,他們正在創造某事。在數據庫中。所以如果我想測試上面的例子,那麼測試異常處理纔有意義。但這個問題並沒有解決。我必須知道在arg2之前是否測試了arg1。 – myAces 2011-04-06 13:19:54

+0

假設doa實現了一些接口,那麼您可以測試daoA是否調用了其'Create'方法,以及doaB。你可以通過設定對模擬的期望來做到這一點。我會在我的答案中添加一些細節。 – 2011-04-06 13:35:16

+0

我想我已經開始明白了。我會通讀你的鏈接並嘗試你所提到的。感謝您的幫助 – myAces 2011-04-06 14:01:58

2

很多時候你只需要假物體而不是嘲笑。模擬對象是爲了測試組件交互,並且通常可以通過直接查詢SUT的狀態來避免這種情況。 mock的大多數實際用途是測試與某些外部系統(數據庫,文件系統,webservice等)的交互,而對於其他事情,您應該能夠直接查詢系統狀態。