Asp.net
在 ASP.NET 中對登錄進行單元測試
我對 TDD 很陌生,我的一個單元測試遇到了麻煩。我似乎無法理解下一步該做什麼。:( 我正在嘗試對我的一個名為 AccountService 的服務進行單元測試,並且我正在測試一個名為 DoLogin(username, password) 的方法。下面是一些範常式式碼:
[Test] public void User_With_Correct_Username_And_Pass_Should_Login_Successfully() { // Arrange var accountService = new AccountService(); // Act bool result = accountService.DoLogin("test", "test"); // Assert Assert.IsTrue(result); } public class AccountService : IAccountService { public bool DoLogin(string username, string password) { if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password)) return false; return true; } }所以這個測試過去了,但現在我該怎麼辦?!我如何真正測試是否發生了有效登錄?我是否需要實施集成測試並針對真實或記憶體數據庫測試登錄?對不起,如果我做的事情完全不正確。我真的希望有一天能把這些 TDD 的東西搞定。謝謝
你的經歷和我剛開始的經歷很相似。雖然我在 TDD 上出售並且不會做任何不同的事情,但我當然理解您的困惑。重要的是要記住 TDD 是一種設計理念。話雖如此,我想我可以幫助消除你的一些挫敗感。
- 首先考慮您要完成的工作,而不是在個人測試級別上,而是您要嘗試做什麼。如果您的任務(使用者故事)涉及獲取一些憑據並嘗試根據這些憑據對目前使用者進行身份驗證,那麼就從那裡開始,一路向下。您似乎正朝著這個方向前進,只是被困在接下來的步驟中
- 在進行單個測試時,請根據預期的行為來考慮它,而不僅僅是驗證一些輸入和輸出。把自己想像成使用這個組件,然後簡單地按照你想要的方式編寫一行程式碼。讓這部分幫助驅動您的服務的介面/契約。你必須問自己一個問題,“如果我呼叫這個方法,我怎麼知道它有效?我希望它做什麼?” 這將決定您需要做出什麼樣的斷言。
- 確定你的外部依賴是什麼,並使用抽象來代替(依賴倒置原則)。如果這些依賴項是您在行為驗證的一部分時所關心的,那麼請使用依賴項注入,以便您可以在測試中使用模擬。
- 永遠,永遠,永遠遵循這個順序
$$ Write your test, watch it fail, code to pass, refactor $$. **從我的錯誤中學習!!!**相信我,這是沒有商量餘地的。否則,當沒有正確使用 TDD 時,您可能會將問題歸咎於 TDD。
好的,因此將所有這些與您的範例以及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); }好的,所以那裡發生了很多事情,也許還有很多需要研究。但是,您可以開始了解如何通過使用更好的設計來進行徹底的測試。在上面的範例中,重要的是要注意 Mock Object 是自定義滾動的,但您不必經歷所有這些痛苦。那裡有許多模擬框架。例如使用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 是一種完整的設計理念。然而,它會帶來更簡潔的程式碼、更好的設計和更少的錯誤。