2011-07-04 61 views
5

我們目前正在使用Autofac作爲IoC容器來跟蹤DI模型。爲什麼要使用Mocking Framework?

我們最近開始研究像MOQ和Rhino Mocks這樣的模擬框架。然而,我們似乎無法證明他們的用法不僅僅是爲我們的每個接口創建Mock實現類。

爲什麼這樣做:

var mock = new Mock<IFoo>(); 
mock.Setup(foo => foo.DoSomething("ping")).Returns(true); 

取而代之的是:

class FooMock : IFoo { 
    bool DoSomething(string input) { 
    return input == "ping"; 
    } 
} 
mock = new FooMock(); 

後者更加詳細,但似乎更靈活,適用於複雜的嘲笑。

+0

這裏有一個類似的問題,可以提供一些見解:http://stackoverflow.com/questions/300177/why-do-i-need-a-mocking-framework-for-my-unittests –

+0

@Jason Down :我會說這不是一個「相似」的問題,而是同一個問題。投票結束重複。 –

+0

@Don Roby:雅,我想這幾乎完全是同一個問題。 –

回答

12

你在你的例子中顯示的更多是一個假的/存根而不是一個真正的模擬,這是事實,如果你只想從一個依賴對象的預先設定的行爲,那麼通常假冒可以是比使用一個嘲諷的框架。

有由Martin Fowler規範的文章討論的事實Mocks aren't Stubs,我已經提離它下面的段落:

這裏的關鍵區別在於我們如何 驗證順序做了正確的 與 倉庫交互的東西。通過狀態驗證,我們 通過針對 倉庫的狀態進行確認。 Mocks使用行爲 驗證,我們在此檢查 以查看訂單是否在倉庫上進行了正確的 調用。

從本質上講,你通常打算檢查你的方法如何作用於依賴 - 你的模擬有期望,你在方法運行後驗證那些期望。

當然,你仍然可以編寫自己的案例模擬,但使用框架將爲您節省大量時間,提供更多可讀的測試並保存測試中的錯誤。

這是特別真實的,因爲你的期望變得越來越複雜,想象有一種方法可以根據輸入參數測試哪種方法調用特定的相關類可變的次數和變化的值 - 寫一個模擬會很複雜對於你自己而言,但是使用一個好的嘲諷框架是微不足道的。

要使用一些代碼演示了,想象這PrintOrders方法(請原諒的愚蠢的例子):

public void PrintForeignOrders(List<Orders> orders) 
{ 
    foreach(var order in orders) 
    { 
     if (order.IsForeign) 
     { 
      printer.PrintOrder(order.Number, order.Name); 
     } 
    } 
} 

你可能會想至少測試:

  • 當列表是空的沒有什麼印
  • 當有外國訂單打印
  • 當有兩個訂單都打印(使用正確的編號和名稱)

有了一個好的模擬框架,對注入的打印機對象設置這些測試只是一些擊鍵問題。

7

然而,我們似乎無法在剛創建模擬 實現類,我們每一個 接口來證明 它們的用法。

這正是一個模擬框架可以節省您的工作 - 創建一個存根或模擬實現,以便能夠測試您的類的行爲。

你在做什麼沒有任何問題,如果對你的項目來說是可行的,盡一切辦法堅持下去 - 對許多人來說,這似乎是一個非常平凡的任務,而這正是使用嘲笑框架可以爲您節省大量時間,並且還避免了代碼庫的膨脹,僅僅用於測試以及在模擬實現中出現額外錯誤的可能性。

9

每次更改接口時,爲了符合新的接口,每個手動編碼的模擬對象(實際上是一個存根)都必須進行調整。

因此,每次更改接口時,手工編碼的很多存根對象都會導致大量的測試代碼維護。然而,模擬框架創建的模擬將始終與更新後的界面兼容。