Asp.net

在 ASP.NET 中對登錄進行單元測試

  • July 9, 2014

我對 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 是一種設計理念。話雖如此,我想我可以幫助消除你的一些挫敗感。

  1. 首先考慮您要完成的工作,而不是在個人測試級別上,而是您要嘗試做什麼。如果您的任務(使用者故事)涉及獲取一些憑據並嘗試根據這些憑據對目前使用者進行身份驗證,那麼就從那裡開始,一路向下。您似乎正朝著這個方向前進,只是被困在接下來的步驟中
  2. 在進行單個測試時,請根據預期的行為來考慮它,而不僅僅是驗證一些輸入和輸出。把自己想像成使用這個組件,然後簡單地按照你想要的方式編寫一行程式碼。讓這部分幫助驅動您的服務的介面/契約。你必須問自己一個問題,“如果我呼叫這個方法,我怎麼知道它有效?我希望它做什麼?” 這將決定您需要做出什麼樣的斷言。
  3. 確定你的外部依賴是什麼,並使用抽象來代替(依賴倒置原則)。如果這些依賴項是您在行為驗證的一部分時所關心的,那麼請使用依賴項注入,以便您可以在測試中使用模擬
  4. 永遠,永遠,永遠遵循這個順序

$$ 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 是一種完整的設計理念。然而,它會帶來更簡潔的程式碼、更好的設計和更少的錯誤。

引用自:https://stackoverflow.com/questions/953257