Unit testing 使用HttpContext.Current.User.Identity.GetUserId()对mvc模型进行单元测试

Unit testing 使用HttpContext.Current.User.Identity.GetUserId()对mvc模型进行单元测试,unit-testing,asp.net-mvc-5,nunit,moq,Unit Testing,Asp.net Mvc 5,Nunit,Moq,在我的MVC5应用程序中,我有一个日志实体,用于记录对任何控制器的任何调用。此日志使用:HttpContext.Current.User.Identity.GetUserId()确定访问控制器的用户的身份 公共类日志 { 公共日志() { TS=日期时间。现在; UserId=HttpContext.Current.User.Identity.GetUserId(); } [必需] 公共Int32 Id{get;set;} 公共字符串用户标识{get;set;} [显示(Name=“TS”,Re

在我的MVC5应用程序中,我有一个日志实体,用于记录对任何控制器的任何调用。此日志使用:
HttpContext.Current.User.Identity.GetUserId()
确定访问控制器的用户的身份

公共类日志
{
公共日志()
{
TS=日期时间。现在;
UserId=HttpContext.Current.User.Identity.GetUserId();
}
[必需]
公共Int32 Id{get;set;}
公共字符串用户标识{get;set;}
[显示(Name=“TS”,ResourceType=typeof(Resources.Models.Log.Log))]
[必需(ErrorMessageResourceType=typeof(Resources.Models.Log.Log),ErrorMessageResourceName=“RequiredTS”)]
公共日期时间{get;set;}
[必需]
公共短日志类型ID{get;set;}
[显示(Name=“LogText”,ResourceType=typeof(Resources.Models.Log.Log))]
公共字符串LogText{get;set;}
公共应用程序用户{get;set;}
}
当我尝试对控制器进行单元测试并装入log类的实例时,会出现以下错误:

引发的异常:System.NullReferenceException:对象引用不正确 设置为对象的实例。 在DASU.Core.Models.Log..ctor()上

我知道这是因为上下文没有设置


因此,我的问题是如何设置上下文,或者如何模拟上下文,以便为测试创建日志?

您应该避免耦合到
HttpContext
。正如在注释中建议的那样,您可以简化日志,将
用户ID
注入到依赖日志类中

公共类日志
{
公共日志(字符串用户ID)
{
TS=日期时间。现在;
UserId=UserId;
}
//…为简洁起见,删除了其他代码
}
或者抽象掉对
HttpContext
的调用,这样您就可以模拟您的抽象并将其注入,而不是尝试和模拟
HttpContext

公共接口提供程序{
字符串GetUserId();
}
生产实现可以封装对
HttpContext
的调用,并且可以轻松地为单元测试创建模拟实现

公共类日志
{
公共日志(IUserProvider userProvider)
{
TS=日期时间。现在;
UserId=userProvider.GetUserId();
}
//…为简洁起见,删除了其他代码
}

您是否使用任何IoC/DI容器?如果是,最好从中获取用户。您可以使用web筛选器将用户从
HttpContext
放入容器中。您可以有一个测试设置,将用户从测试上下文放入容器中。显然,这不适用于单元测试,因为它们不关心用户。这只是用于集成测试。如果您有一个正在测试的单元,它在测试期间不可避免地调用另一个单元(在您的情况下,Log和HttpContext是其他单元),那么您不是在进行单元测试。更好地分离单元。要求用户ID作为构造函数的参数,而不是像那样保留隐藏的依赖项,这将容易得多。