我對單元測試非常熟悉,並且瞭解模擬和存根之間的區別。 Roy Osherove最簡單的解釋是,所有的假貨都是以存根的形式出現,直到你對他們斷言,然後他們是嘲弄。使用單個假作爲模擬和存根
同樣,我明白了。我的問題是「這是錯誤的使用一個假的情況下同時作爲模擬和存根?就拿從犀牛嘲笑文檔下面的例子(http://ayende.com/wiki/Rhino+Mocks+3.5.ashx)
public void When_user_forgot_password_should_save_user()
{
var mockUserRepository = MockRepository.GenerateMock<IUserRepository>();
var stubbedSmsSender = MockRepository.GenerateStub<ISmsSender>();
var theUser = new User{HashedPassword = "this is not hashed password"};
mockUserRepository.Stub(x => x.GetUserByName("ayende")).Return(theUser);
mockUserRepository.Expect(x => x.Save(theUser));
var controllerUnderTest = new LoginController(mockUserRepository, stubbedSmsSender);
controllerUnderTest.ForgotMyPassword("ayende");
mockUserRepository.VerifyAllExpectations();
}
你會發現mockUserRepository進行命名mock這個詞,並且正在調用GenerateMock工廠,因爲進一步在代碼中mockUserRepository具有爲其建立的行爲期望,並且最終期望行爲正在被驗證。很好,但是沿着mockUserRepository調用它的Stub()方法「可以」通過調用GetUserByName()返回的數據在同一個對象上
顯然,這個例子顯示了使用明確的na醫學和宣稱模擬既是一個模擬和存根。回到Roy Osherove的定義,即所有的假貨都是存根,直到你對他們斷言,我不得不相信,使用假貨作爲模擬和存根(雖然當然有效)是不好的做法。
有沒有人知道這樣做是否有判決?
我不同意每個模擬都是一個存根,也不是我說的。我說每一個「假」都是作爲一個存根開始的,根據你的使用方式,它可能會變成一個模擬。 這僅僅意味着我們需要爲2個可能的原因創建一個假對象(假的輸入到被測試的方法或假的與外部系統的交互),但除非我們堅持反對假冒,假冒屬於類別的一個存根。如果你堅持反對它,唯一一次你的假可以準確地稱爲模擬。 – user1739635
這不是主要觀點。假設一些代碼不會'int i = foo.getValue(); foo.setValue(i * 2);'。如果你想測試這個方法,你需要存儲foo,以便getValue()返回一個整數,例如5。爲了確保它使用10調用foo.setValue(),就像它應該做的那樣,你需要驗證foo.setValue()已經被調用了10,從而使用stub作爲模擬。你沒有選擇。該代碼不使用2個不同的foos。它只使用一個。所以,存根也需要是一個模擬。 –
是的,但這些將是兩個不同的測試,因此在一個測試中,我需要存根foo.getValue(),以便它將返回我的方法在測試期望的罐頭數據,並且我將對我的方法測試。而且,在另一個測試中,我需要模擬foo.setValue()並聲明它被調用。不應該有一個測試來處理這兩種情況。 – user1739635