首页 > 解决方案 > 单元测试 HttpContext.GetOwinContext()

问题描述

我刚刚开始为我们的代码创建单元测试。我们使用 ASP.NET MVC 4 和 Owin 中间件进行身份验证以及其他数据和用户数据库操作。

因此,首先我们有几个控制器和基于控制器。在基础控制器上,我们添加了常见的代码,如UserManager,RoleManager等。这些代码使用HttpContext.GetOwinContext. 在其中一个控制器上实施单元测试时,我需要创建一个我目前正在努力做的基本控制器的单元测试。

代码如下所示:

protected IAuditRepository Audit
{
    get { return _audit ?? (_audit = DependencyResolver.Current.GetService<IAuditRepository>()); }
}

protected UserManager UserManager
{
    get { return HttpContext.GetOwinContext().GetUserManager<UserManager>(); }
}

因此,我对如何测试 HttpContext.GetOwinContext 进行了研究,但是,我看到的大部分内容都不清楚,并且没有为我提供太多信息来创建测试。

我已尝试成功使用 Moq 进行依赖注入,但我无法在 HttpContext 中使用。请任何人都可以让我走上正确的道路哦如何测试这些代码?

标签: c#asp.netunit-testingowin

解决方案


如您所知,单元测试可以帮助您重构代码。

你已经到了一个地步,你看到你的代码是耦合的,你依赖于HttpContext(慢慢呼吸,敌人就在你面前,但你很快就会顺利击败他)

现在你对如何重构它有了一个提示。使UserManager成为依赖项并将其注入控制器的构造函数中。

然后,您将能够模拟它,并最终得到一个耦合度较低的解决方案。

此外,您很快就会看到使用 Service Locator 检索 AuditManager。这会让你遇到运行时错误的痛苦。更好的方法是也注入它。

这就是单元测试的魅力所在!

public class CustomController:BaseController /*Maybe you dont need BaseController anymore if it only provides you dependencies*/
{  
    protected UserManager _userManager{get;} //equals to readonly
    protected AuditManager _auditManager {get;} //equals to readonly

   public CustomController(IAuditManager auditManager,UserManager userManager)
   {
       _userManager=userManager;
       _auditManager=auditManager;
   }

}



//Unit test
[Test]
public void CustomController_WithMockedUserManager_IsAbleToTest()
{
      CustomController = new CustomController( yourMockedUserManager, yourMockedAuditManager);
     //Asserts...etc

}

推荐阅读