我刚开始为代码创建单元测试。我们使用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中使用。请任何人都可以把我放在正确的道路上哦如何测试这些代码?
如您所知,单元测试可帮助您重构代码。
你已经到了一个点,你看到你的代码是耦合的,你依赖于HttpContext(慢慢地呼吸,敌人在你面前,但你很快就会击败他)
现在你有一个关于如何重构它的提示。使UserManager成为依赖项并将其注入控制器的构造函数中。
然后,您将能够模拟它,并最终得到一个耦合较少的解决方案。
此外,您很快就会看到使用Service Locator检索Audit Manager。那会让你的运行时错误变得痛苦。更好的方法是注入它。
这是单元测试魔力的一部分!
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
}