2010-10-25 72 views
5

我正在做有序的期望在犀牛模擬中描述的由ayende在this後。我的代碼看起來像這樣:重複使用已驗證的模擬

using (_mocks.Ordered()) 
    { 
    Expect.Call(() => _myMock.CallA()); 
    Expect.Call(() => _myMock.CallB(40)); 
    Expect.Call(() => _myMock.CallA()); 
    } 
    _mocks.ReplayAll(); 
    _myObjectUnderTest.DoStuff(); 
    _mocks.VerifyAll(); 

在此之後,我想添加更多的期望和測試我的對象的更多方法。我想這樣做是因爲我有一些基本的測試方法可以在我的測試對象上做一些設置,我不想重新測試這個功能,所以我只是調用早期的測試方法。如果我在VerifyAll()後嘗試添加更多期望,我會得到一個異常:「當模擬對象處於已驗證狀態時,此操作無效。」

我的問題的一部分是我真的不明白什麼是所有的重播/驗證的東西在做什麼,我只是複製代碼。我使用嚴格的模擬,所以任何設置代碼都必須具有匹配的期望或失敗。我不想重複我的設置代碼的期望。

有沒有辦法重置模擬以準備好以某種方式重新開始?

回答

4

簡答題:沒有。現在到了很長的答案。

什麼重播和驗證的東西是這樣的。在致電ReplayAll之前,您正在告訴犀牛您期望的方法將要做什麼。您在某種意義上正在記錄對您創建的模擬對象的調用。

在記錄了方法調用之後,您可以撥打ReplayAll告訴Rhino,您現在要做一些應該執行記錄的方法的東西。

最後,你打電話給VerifyAll,要求Rhino驗證這些方法是否被實際調用,因爲你已經記錄了它們。

現在來談談爲什麼你真的不想重新使用模擬。通過單元測試/ TDD,您的單元測試應儘可能少地測試。這是爲了讓你的單元測試簡單而透明。單元測試的整個想法是,許多很多測試作爲整體測試整個系統。

有關TDD解釋此問題和其他主題的非常好的演示文稿,請參閱http://www.infoq.com/presentations/integration-tests-scam

PS:一個小細節:只要方法不返回結果,你可以寫:

using (_mocks.Ordered()) 
{ 
    Expect.Call(() => _myMock.CallA()); 
    Expect.Call(() => _myMock.CallB(40)); 
    Expect.Call(() => _myMock.CallA()); 
} 

爲:

using (_mocks.Ordered()) 
{ 
    _myMock.CallA(); 
    _myMock.CallB(40); 
    _myMock.CallA()); 
} 

(至少在最新版本犀牛)

+0

問題出現在我想測試B時,但必須先調用A以便首先爲B設置所有內容。如果A在我的模擬上調用方法,那麼我必須期待它們,否則使用動態模擬而不是嚴格模擬。我想不要重複所有的期望,因爲我已經徹底地測試了A. – captncraig 2010-10-28 04:25:41

+1

是的,我也有這個問題。你有兩個選擇。首先是修改業務邏輯,以便控制哪些部件被觸發,或者將業務邏輯分成獨立測試的較小部分。第二種選擇是將一些期望提升到你的'[TestFixture]'的私有方法,並在兩個測試中調用它。我做了最後一個(現在)。 – 2010-10-28 06:26:23

+0

-1,因爲我有這個問題,但找到了解決方法,否定了這個答案(見其他帖子 - 「簡短回答:是」) – brewmanz 2014-11-04 21:29:23

0

簡短的回答:是的

較長的答案:請嘗試以下

[Test] 
    public void RhinoMock_PerformMultipleChecks() 
    { 
     var myMock = MockRepository.GenerateDynamicMockWithRemoting<IComparable>(); 

     // first round of checks 
     myMock.Expect(x => x.CompareTo("123")).Return(1); 
     myMock.Expect(x => x.CompareTo("-12")).Return(-1); 
     Assert.AreEqual(1, myMock.CompareTo("123")); 
     Assert.AreEqual(-1, myMock.CompareTo("-12")); 
     myMock.VerifyAllExpectations(); 

     // reset 
     myMock.BackToRecord(); 
     myMock.Replay(); 

     // next round of checks 
     myMock.Expect(x => x.CompareTo(1.23)).Return(1); 
     myMock.Expect(x => x.CompareTo(-12)).Return(-1); 
     Assert.AreEqual(1, myMock.CompareTo(1.23)); 
     Assert.AreEqual(-1, myMock.CompareTo(-12)); 
     myMock.VerifyAllExpectations(); 

     // reset 
     myMock.BackToRecord(); 
     myMock.Replay(); 

     // final round of checks 
     myMock.Expect(x => x.CompareTo(1.23m)).Return(1); 
     myMock.Expect(x => x.CompareTo(-12m)).Return(-111); 
     Assert.AreEqual(1, myMock.CompareTo(1.23m)); 
     Assert.AreEqual(-111, myMock.CompareTo(-12m)); 
     myMock.VerifyAllExpectations(); 
    }