你的經驗是非常相似的礦山開始了。雖然我在TDD上銷售,不會做任何不同的事情,但我當然明白你的困惑。重要的是要記住TDD是一種設計理念。話雖如此,我想我可以幫助清除你的一些挫折。
從考慮你想要完成的事情開始,而不是在單獨的測試級別上,但是你試圖做什麼。如果您的任務(用戶故事)涉及獲取某些憑證並嘗試根據這些憑證對當前用戶進行身份驗證,那麼請從此處開始並按順序進行。 你似乎在這個方向前進,只是卡住在接下來的步驟中
在單獨的測試工作時,在expected behavior方面,而不是僅僅檢驗一些輸入和輸出想到它。把你自己想象成使用這個組件,並且簡單地按照你想要的方式編寫一行代碼。讓這部分幫助驅動你的服務的接口/合同。你必須問自己這個問題:「如果我打電話給這個方法,我怎麼知道它的工作原理?我期望它做什麼?」這將決定你需要做什麼樣的斷言。
確定你的外部依賴是什麼,和utilize abstractions instead(依賴倒置原則)。如果這些依賴關係是您關心的行爲驗證的一部分,請使用dependency injection,以便您可以在測試中使用mock。
總是,總是按照這個順序[寫下你的測試,看它失敗,代碼通過,重構]。 從我的錯誤中學習!相信我,這是不可協商的。否則,當TDD沒有被正確使用時,你有責任責怪你的問題。
好了,你的榜樣把所有這些組合起來,有些很好的提供test cases from lance,我們可以做這樣的事情:
[Test]
public void ShouldAuthenticateValidUser()
{
IMyMockDa mockDa = new MockDataAccess();
var service = new AuthenticationService(mockDa);
mockDa.AddUser("Name", "Password");
Assert.IsTrue(service.DoLogin("Name", "Password"));
//Ensure data access layer was used
Assert.IsTrue(mockDa.GetUserFromDBWasCalled);
}
[Test]
public void ShouldNotAuthenticateUserWithInvalidPassword()
{
IMyMockDa mockDa = new MockDataAccess();
var service = new AuthenticationService(mockDa);
mockDa.AddUser("Name", "Password");
Assert.IsFalse(service.DoLogin("Name", "BadPassword"));
//Ensure data access layer was used
Assert.IsTrue(mockDa.GetUserFromDBWasCalled);
}
好了,所以有很多事情在那裏,也許很多研究。但是,您可以開始瞭解如何通過使用更好的設計來進行徹底測試。在上面的例子中,重要的是要注意,模擬對象是自定義滾動的,但你不必經歷所有這些痛苦。那裏有很多模擬框架。例如使用RhinoMocks,您的測試應該是這樣的:
[Test]
public void ShouldAuthenticateValidUser()
{
var mockRepo = new MockRepository();
var mockDa = mockRepo.DynamicMock<IMyMockDa>();
var service = new AuthenticationService(mockDa);
using(mockRepo.Record())
{
//I realize this is a terrible method and should not exist if you
// care about security, but for demonstration purposes...
Expect.Call(mockDa.GetPassword("User")).Return("Password");
}
using(mockRepo.Playback())
{
Assert.IsTrue(service.DoLogin("User", "Password"));
}
}
習慣於先做事手工的方式,所以你理解的概念,然後移動到使用的框架。呼!很多信息,但正如你所看到的,TDD是一個完整的設計理念。但是,它會產生更清晰的代碼,更好的設計和更少的錯誤。
很酷,謝謝。所以在完成DoLogin的測試列表後,我的下一步是什麼?然後,我真的測試登錄對數據庫? – CalebHC 2009-06-04 23:28:31
如果您認爲在將參數發送到存儲過程並從存儲過程獲得正確結果方面存在足夠的風險,那麼當然! 測試有助於降低風險並改善代碼。我推薦您在任何地方合理預測任何機會的測試。 – lance 2009-06-05 14:23:58