2009-06-04 34 views
5

Tôi rất mới đối với TDD và tôi gặp sự cố với một trong các bài kiểm tra đơn vị của mình. Tôi dường như không thể hiểu được việc cần làm tiếp theo. . :(Tôi đang cố gắng để kiểm tra đơn vị một dịch vụ của tôi gọi AccountService và tôi đang thử nghiệm một phương pháp gọi là DoLogin (username, password) Dưới đây là một số mã ví dụ:Đơn vị Kiểm tra Đăng nhập trong ASP.NET

[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; 
     } 
    } 

Vì vậy, thử nghiệm này quá khứ nhưng bây giờ những gì làm Làm thế nào để tôi thực sự thử nghiệm nếu một đăng nhập hợp lệ xảy ra? Tôi có cần phải thực hiện một thử nghiệm tích hợp và kiểm tra đăng nhập với một DB thực hoặc trong bộ nhớ? Xin lỗi nếu tôi đang làm những điều hoàn toàn không chính xác. ngày để có được công cụ TDD này xuống. Cảm ơn

Trả lời

14

Kinh nghiệm của bạn là rất tương tự như tôi bắt đầu. Trong khi tôi được bán trên TDD và sẽ không làm bất cứ điều gì khác nhau, tôi chắc chắn hiểu sự nhầm lẫn của bạn. Điều quan trọng cần nhớ là TDD là một triết lý thiết kế. Điều đó đang được nói, tôi nghĩ rằng tôi có thể giúp làm sáng tỏ một số sự thất vọng của bạn.

  1. Bắt đầu bằng cách suy nghĩ về những gì bạn đang cố gắng hoàn thành, không phải ở cấp độ thử nghiệm cá nhân, nhưng bạn đang cố gắng làm gì. Nếu nhiệm vụ của bạn (câu chuyện người dùng) liên quan đến việc lấy một số thông tin xác thực và cố gắng xác thực người dùng hiện tại dựa trên các thông tin đăng nhập đó, sau đó bắt đầu từ đó và làm việc theo cách của bạn. Bạn dường như được nhóm theo hướng này, chỉ bị mắc kẹt trên các bước tiếp theo

  2. Khi làm việc trên một thử nghiệm cá nhân, suy nghĩ của nó về mặt expected behavior thay vì chỉ kiểm tra một số đầu vào và đầu ra. Hãy suy nghĩ về bản thân bạn khi sử dụng thành phần này, và chỉ cần viết một dòng mã theo cách bạn muốn nó được viết. Hãy để phần này giúp thúc đẩy giao diện/hợp đồng dịch vụ của bạn. Bạn phải tự hỏi mình câu hỏi, "Nếu tôi gọi phương pháp này, làm thế nào tôi biết nó hoạt động? Tôi sẽ mong đợi nó sẽ làm gì?" Điều này sẽ xác định loại xác nhận bạn cần thực hiện.

  3. Xác định phụ thuộc bên ngoài của bạn là gì và utilize abstractions instead (nguyên tắc đảo ngược phụ thuộc). Nếu những phụ thuộc này là thứ bạn quan tâm như là một phần của xác minh hành vi của bạn, thì hãy sử dụng dependency injection để bạn có thể sử dụng mock trong thử nghiệm của mình.

  4. Luôn luôn, luôn luôn, luôn tuân theo thứ tự này [Viết thử nghiệm của bạn, xem nó không thành công, mã để vượt qua, refactor]. TÌM HIỂU TỪ MISTAKES CỦA TÔI !!! Tin tôi đi, điều này không thể thương lượng được. Nếu không, bạn có trách nhiệm đổ lỗi cho các vấn đề của bạn trên TDD khi nó không được sử dụng đúng cách.

Ok, vì vậy việc đưa tất cả điều này cùng với ví dụ của bạn, và một số độc đáo cung cấp test cases from lance, chúng ta có thể làm điều gì đó như thế này:

[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); 
} 

Ok, vì vậy có rất nhiều xảy ra ở đó, và có lẽ rất nhiều để nghiên cứu. Tuy nhiên, bạn có thể bắt đầu xem làm thế nào nó có thể làm kiểm tra kỹ lưỡng bằng cách sử dụng thiết kế tốt hơn. Trong các ví dụ trên, điều quan trọng cần lưu ý là đối tượng Mock là tùy chỉnh được cuộn, nhưng bạn không phải trải qua tất cả nỗi đau này. Có rất nhiều Mocking Frameworks ngoài kia. Ví dụ sử dụng RhinoMocks, kiểm tra của bạn sẽ trông như thế này:

[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")); 
    } 
} 

Get sử dụng để làm mọi thứ theo cách thủ công đầu tiên để bạn hiểu các khái niệm, và sau đó chuyển sang sử dụng một khuôn khổ. Whew! Rất nhiều thông tin, nhưng như bạn có thể thấy, TDD là một triết lý thiết kế toàn bộ. Tuy nhiên, nó sẽ dẫn đến mã sạch hơn, thiết kế tốt hơn và ít lỗi hơn.

+1

Cảm ơn bạn rất nhiều vì đã dành thời gian để viết điều này! Tôi rất trân trọng điều này. Bạn đã nói rất nhiều thứ hay và có lẽ tôi sẽ mất một lúc để nắm bắt mọi thứ. Bạn nói đúng là tôi phải suy nghĩ khác khi làm TDD. Hy vọng rằng sự nhầm lẫn của tôi một ngày nào đó sẽ trôi qua, nhưng điều đó sẽ chỉ mất thời gian. Cảm ơn một lần nữa! – CalebHC

+0

Phải mất một thời gian dài trước khi tôi có thời điểm "Ah Ha", nhưng bây giờ tôi hoàn toàn được chuyển đổi. Tôi sẽ khuyến khích bạn kiểm tra một bài đăng SO khác mà tôi đã thực hiện về TDD: http://stackoverflow.com/questions/106800/unit-testing-guidelines/106813#106813 – Josh

+1

Kết xuất đồ họa mà bạn thấy là lỗi đã biết với câu trả lời cũ - bạn có thể sửa lỗi này cho bất kỳ câu trả lời nào (không chỉ riêng câu trả lời của bạn) bằng cách gửi bất kỳ chỉnh sửa nào, buộc phải trả lời câu trả lời. Điều này cũng giải thích tại sao nó có vẻ tốt khi bạn lần đầu tiên đưa lên trình soạn thảo. Tôi đã cập nhật định dạng ở đây, nhưng bạn cũng có thể gửi bản chỉnh sửa sơ khai và hoàn tác nó và nó vẫn sẽ buộc câu trả lời phải hiển thị lại. – BoltClock

0

Bạn nên có một bài kiểm tra đó tên người dùng hợp lệ hoặc mật khẩu không hợp lệ gây DoLogin() để thất bại.

với tên chức năng, (DoLogin() thay vì sau đó CheckLogin()) Tôi nghĩ rằng chức năng nên có một số tác dụng phụ là tốt. Thử nghiệm nên xác minh rằng tác dụng phụ. Thực sự cần phải làm rõ những gì trước khi ai đó có thể làm rõ làm thế nào nó cần được xác minh.

1

Chuyển những gì bạn biết là thông tin đăng nhập hợp lệ và không hợp lệ cho DoLogin và sau đó so sánh kết quả với những gì bạn mong đợi. Hãy thử tưởng tượng mọi kết hợp có thể (đọc: hợp lý)/đầu vào của thông số "tên người dùng" và "mật khẩu" mà người dùng sẽ cung cấp và tạo một thử nghiệm cho mỗi người dùng.

Nếu logic kinh doanh DoLogin của bạn được tin tưởng, chúng tôi sẽ xác định tên người dùng "hợp lệ" (và mật khẩu "hợp lệ") là bất kỳ thứ gì được điền. Đủ công bằng, vì lợi ích của cuộc thảo luận.

Một số xét nghiệm đơn giản tôi suy nghĩ:

Login_With_Null_UserName_Fails() 
Login_With_Populated_UserName_Succeeds() 
Login_With_Empty_UserName_Fails() 
Login_With_Null_Password_Fails() 
Login_With_Populated_Password_Succeeds() 
Login_With_Empty_Password_Fails() 

Hoặc, hãy xem xét kết hợp:

Login_With_Null_UserName_And_Populated_Password_Fails() 
Login_With_Populated_UserName_And_Populated_Password_Succeeds() 
Login_With_Empty_UserName_And_Null_Password_Fails() 
etc 
etc 
+0

Tuyệt vời, cảm ơn. Vì vậy, sau khi tôi thực hiện hết danh sách kiểm tra của mình cho DoLogin bước tiếp theo của tôi là gì? Tôi có thực sự kiểm tra đăng nhập với DB không? – CalebHC

+0

Nếu bạn cho rằng có đủ rủi ro trong các tham số gửi của bạn và nhận được kết quả chính xác từ các thủ tục được lưu trữ của bạn, chắc chắn! Kiểm tra giúp giảm rủi ro và cải thiện mã. Tôi khuyên bạn nên kiểm tra bất cứ nơi nào bạn dự đoán hợp lý một trong hai cơ hội. – lance

Các vấn đề liên quan