2013-02-15 45 views
9

我剛剛開始閱讀Professional Test Driven Development with C#: Developing Real World Applications with TDD瞭解存根,假貨和嘲笑。

我很難理解存根,假貨和嘲笑。從我目前瞭解的情況來看,它們是用於單元測試項目目的的假對象,並且模擬是一個存在條件邏輯的存根。

另一件我認爲我已經選擇的事情是,嘲笑與依賴注入有關,這是我昨天才理解的一個概念。

我沒有得到的是爲什麼我會真正使用它們。我似乎無法在網上找到任何具體的例子來正確解釋它們。

任何人都可以向我解釋這個概念嗎?

+2

閱讀本http://xunitpatterns.com/Mocks,%20Fakes,%20Stubs%20and%20Dummies.html這http://martinfowler.com/articles/mocksArentStubs.html – blank 2013-02-15 10:13:16

+1

雖然你在你不妨閱讀這個http://www.mockobjects.com/files/mockrolesnotobjects.pdf – blank 2013-02-15 10:21:18

+0

我希望你能赦免商業廣告,但是我們寫了一本完整的書「面向對象的軟件」,解決了動機使用嘲笑。 – 2013-04-27 10:52:39

回答

19

正如我過去讀過,這裏是什麼,我相信每個詞代表

存根

這裏你磕碰到已知值的方法的結果,只是爲了讓代碼運行沒有問題。例如,可以說你有以下幾點:

public int CalculateDiskSize(string networkShareName) 
{ 
    // This method does things on a network drive. 
} 

你不在乎這個方法的返回值是什麼,它是不相關的。另外,如果網絡驅動器不可用,則可能會導致異常。所以你存根結果,以避免該方法潛在的執行問題。

所以,你最終做類似:

sut.WhenCalled(() => sut.CalculateDiskSize()).Returns(10); 

與你正在返回假數據,或創建一個對象的實例僞造假的。一個典型的例子是存儲庫類。採取這種方法:

public int CalculateTotalSalary(IList<Employee> employees) { } 

通常上述方法將傳遞從數據庫中讀取的僱員的集合。但是在你的單元測試中,你不想訪問數據庫。所以你創建一個假的員工列表:

IList<Employee> fakeEmployees = new List<Employee>(); 

然後,您可以將項目添加到fakeEmployees並斷言預期的結果,在這種情況下,工資總額。

嘲笑

當使用模擬對象,你打算驗證某些行爲,或數據,這些模擬對象。例如:

要驗證一個特定的方法是試運行期間執行,這是一個使用起訂量嘲諷框架一般示例:

public void Test() 
{ 
    // Arrange. 
    var mock = new Mock<ISomething>(); 

    mock.Expect(m => m.MethodToCheckIfCalled()).Verifiable(); 

    var sut = new ThingToTest(); 

    // Act. 
    sut.DoSomething(mock.Object); 

    // Assert 
    mock.Verify(m => m.MethodToCheckIfCalled()); 
} 

希望上面有助於澄清事情有點。

編輯: Roy Osherove是測試驅動開發的知名倡導者,他有一些關於該主題的非常好的信息。您可能會發現它非常有用:

http://artofunittesting.com/

+0

非常翔實。我一直認爲假貨和嘲笑是可以互換的。我每天都會在這裏學習新東西:) +1 – bas 2013-02-15 11:20:45

+0

Mocks裏有什麼'm'?並且是我們正在測試的課程的東西? – fersarr 2015-08-19 09:54:12

+0

'm'是一個傳遞給'Expect()'函數的參數。這是一個lambda表達式。它不在任何地方聲明,它只存在於'Expect()'lambda中。 'var mock = new Mock ();'表示你正在創建一個實現'ISomething'的對象,所以'ISomething'是一個接口,而不是一個對象。然後,您可以使用'mock'來控制方法在被調用時如何響應,例如通過'Expect()'函數。 – 2015-08-19 10:37:03

0

這個PHP單位手冊幫了我很多的介紹:

「有時它只是普通的硬盤測試測試(SUT)的系統,因爲它取決於在測試環境中無法使用的其他組件上,這可能是因爲它們不可用,它們不會返回測試所需的結果,或者因爲執行它們會產生不良的副作用;在其他情況下,我們的測試策略要求我們對SUT的內部行爲有更多的控制或可見性。「更多:https://phpunit.de/manual/current/en/test-doubles.html

而我找到更好的「介紹」時,尋找「測試雙打」作爲嘲笑,假貨,存根和其他人都知道。

3

它們都是測試倍數的變體。這裏是一個很好的參考,說明它們之間的差異:http://xunitpatterns.com/Test%20Double.html

此外,從Martin Fowler的帖子:http://martinfowler.com/articles/mocksArentStubs.html

梅薩羅斯使用術語測試替身作爲任何形式的 通稱假裝對象使用代替用於測試目的的真實對象。 這個名字來源於電影中特技雙人的概念。 (其中一個 他的目標是避免使用已被廣泛使用的任何名稱。) 梅薩羅斯則定義了四個特定種類的雙:

  1. 虛擬對象:圍繞通過,但從來沒有實際使用。通常他們 只是用來填充參數列表。
  2. 虛假對象實際上有工作的實現,但通常採取一些快捷方式,使得它們不適合生產(內存數據庫是一個好的 示例) 。
  3. 存根提供測試過程中調用的罐裝答案, 通常完全不會響應測試以外 中編程的任何內容。存根也可以記錄關於呼叫的信息,例如 電子郵件網關存根,其記錄它「發送」的消息,或者可能僅記錄它「發送」的消息數量。
  4. 模擬是我們在這裏談論的對象:預先編程有預期的對象,它們構成了預期接收的呼叫的 規範。

在這些雙打中,只有嘲諷堅持行爲驗證。其他雙打可以並且通常使用狀態驗證。 Mocks 在練習階段的表現與其他雙打一樣,因爲他們需要讓SUT相信它正在與其真正的 協作者交談。