我有一个方法,我在C#/ ASP.Net Web项目中添加了单元测试。该方法已被其他人修改为包含对包装HttpContext的类的静态方法的调用(以添加一些会话状态),但在测试期间我没有HttpContext,因此抛出空引用异常。任何想法如何解决这个问题?如果我能提供帮助,我不想对生产代码进行太多更改。
待测方法:
public int MethodUnderTest()
{
...
// Added line which breaks the tests
StaticClass.ClearSessionState();
}
在StaticClass中:
public void ClearSessionState()
{
HttpContext.Current.Session["VariableName"] = null;
}
这会抛出NullReferenceException
因为HttpContext.Current
在测试期间为空。
答案 0 :(得分:1)
就使用HttpContext.Current
的单元测试方法而言,你几乎处于死胡同。正确的方法是修改此代码以使用构造函数注入:
private readonly HttpContextBase _context;
public Foo(HttpContextBase context)
{
_context = context;
}
public void ClearSessionState()
{
_context.Session["VariableName"] = null;
}
现在您可以在单元测试中模拟此HttpContextBase。
答案 1 :(得分:1)
在调用StaticClass.ClearSessionState()
行之前,可以使用mock / stub对象设置HttpContext.Current。
答案 2 :(得分:1)
您可以在生产代码中执行自己的静态“注入”,如下所示:
public static class StaticClass {
public void ClearSession() {
TheContext["VariableName"] = null;
}
public static HttpContextBase TheContext{
get {
if (_context == null)
_context = new HttpContextWrapper(HttpContext.Current);
return _context; }
set { _context = value; }
}
}
然后,实际测试变得非常简单,只需在测试之前将TheContext属性设置为存根实例。例如,在Moq中,这样的存根可以设置为一行:
StaticClass.TheContext = new Mock<HttpContextBase>(){DefaultValue = DefaultValue.Mock}.Object;
答案 3 :(得分:0)
最后,我可以删除对StaticClass.ClearSessionState()
的调用,但感谢所有答案。有用的东西。