单元测试结果中出现NullReferenceException
本文关键字:NullReferenceException 测试结果 单元 | 更新日期: 2023-09-27 18:22:19
我刚刚开始用C#Webforms编程(以前有VB Webforms的经验),我正在开发一个web应用程序,它将成为一个更大项目的一小部分。
我已经创建了3个独立的项目,一个用于web表单,一个为类库,一个则用于测试。
我已经将所有项目添加到一个解决方案中,并添加了适当的引用,Webforms和Tests项目都引用了类库。
我在类库中有一个类,它可以找到登录用户的用户名:
public class LoggedInUser
{
public string UserName
{
get { return HttpContext.Current.User.Identity.Name; }
}
}
在我的一个页面的页面加载事件中,我使用这个类来设置文字的text属性,以在屏幕上显示名称。
protected void Page_Load(object sender, EventArgs e)
{
LoggedInUser CurrentUser = new LoggedInUser();
LitUser.Text = string.Format(" {0}", CurrentUser.UserName);
}
这很好用。
为了完成,我想我应该写一个单元测试,以确保登录的用户名是我所期望的。
[TestMethod]
public void Test_Logged_In_User_Name()
{
LoggedInUser actualUser = new LoggedInUser();
string expectedUserName = "myUserName";
string actualUserName = actualUser.UserName;
Assert.AreEqual(expectedUserName, actualUserName);
}
当我运行测试时,它抛出以下异常:
System.NullReferenceException: Object reference not set to an instance of an object
在这条线上:
get { return HttpContext.Current.User.Identity.Name; }
任何想法都将一如既往地受到极大的赞赏。
您需要为HttpContext创建一个包装器类,该类抽象了您需要的功能。原因是HttpContext只存在于web请求,并且当您从应用程序运行单元测试时,HttpContext将不存在。
此外,任何第三方依赖都应该为其创建一个包装器,以帮助进行测试。
值得注意的是,你根本不应该需要这个测试。在这种情况下,您正在测试第三方代码,这是您所依赖的准确代码。单元测试的目的是测试你自己的代码/逻辑,如果你为每一个第三方方法编写测试,你就永远不会发布产品:)。
至于创建包装类,它们与普通类没有什么不同。您需要为HttpContext类创建一个接口,然后创建一个类似以下内容的包装器:
public class HttpContextWrapper
{
private readonly IHttpContext _httpContext;
public HttpContextWrapper()
{
_httpContext = HttpContext.Current;
}
public HttpContextWrapper(IHttpContext injectedContext)
{
_httpContext = injectedContext;
}
public string GetName()
{
_httpContext.Current.User.Identity.Name;
}
}
然后,您可以注入HttpContext的伪实现来获得您想要的结果。
实际上,您不一定需要包装和模拟HttpContext。在你的测试设置中,你可以做一些类似于以下的事情:
var sb = new StringBuilder();
TextWriter writer = new StringWriter(sb);
HttpContext.Current = new HttpContext(
new HttpRequest("path", "http://dummy", ""),
new HttpResponse(writer)
)
{
User = new WindowsPrincipal(WindowsIdentity.GetCurrent())
};
在这个例子中,我用当前用户的身份分配了一个windows主体,但在您的场景中,您可能想要分配一个特制的主体,例如ClaimsPrincipal或伪实现(或mock)。