asp.net - 在 ASP.NET 中对登录进行单元测试

标签 asp.net unit-testing tdd

我对 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 是一种设计理念。话虽如此,我想我可以帮助消除你的一些挫败感。

  • 首先考虑您要完成的工作,而不是在个人测试级别上,而是您要尝试做什么。如果您的任务(用户故事)涉及获取一些凭据并尝试根据这些凭据对当前用户进行身份验证,那么从那里开始并逐步进行。您似乎正朝着这个方向前进,只是在接下来的步骤中卡住了
  • 在进行单个测试时,请根据 expected behavior 进行思考。而不仅仅是验证一些输入和输出。把自己想象成使用这个组件,然后简单地按照你想要的方式编写一行代码。让这部分帮助驱动您的服务的接口(interface)/契约(Contract)。你必须问自己一个问题,“如果我调用这个方法,我怎么知道它有效?我希望它做什么?”这将决定您需要做出什么样的断言。
  • 确定你的外部依赖是什么,utilize abstractions instead (依赖倒置原则)。如果这些依赖关系是您作为行为验证的一部分所关心的,那么使用 dependency injection所以你可以使用 mock在你的测试中。
  • 永远,永远,永远遵循这个顺序[编写你的测试,看着它失败,代码通过,重构]。 从我的错误中学习!!! 相信我,这是没有商量余地的。否则,当没有正确使用 TDD 时,您可能会将问题归咎于 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);
    }
    

    好的,所以那里发生了很多事情,也许还有很多需要研究。但是,您可以开始了解如何通过使用更好的设计来进行彻底的测试。在上面的示例中,重要的是要注意 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 是一种完整的设计理念。然而,它会带来更简洁的代码、更好的设计和更少的错误。

    关于asp.net - 在 ASP.NET 中对登录进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/953257/

    相关文章:

    javascript - Jest.js - 测试是否已调用组件方法(React.js)

    html - TDD/测试 CSS 和 HTML?

    .net - 堆栈溢出时的编辑控制

    asp.net - .NET StreamReader 不会关闭

    python - 在python中模拟函数的局部变量

    ruby-on-rails - 使用 Mocha 进行模拟实际上如何让您测试函数中的逻辑?

    ruby - capybara - 无法点击链接

    c# - 使用构建管理器类加载 ASPX 文件并填充其控件

    c# - ASP.net 中的 OnCLick 问题

    android - 使用 ProGuard,对测试策略有何影响?