代码之家  ›  专栏  ›  技术社区  ›  Jackson Pope

通过调用包装httpContext的静态类对类进行单元测试

  •  1
  • Jackson Pope  · 技术社区  · 15 年前

    我有一个方法,在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 测试期间为空。

    4 回复  |  直到 15 年前
        1
  •  1
  •   Darin Dimitrov    15 年前

    就使用的单元测试方法而言,您在这里几乎处于死胡同 HttpContext.Current 有关。正确的方法是修改此代码以使用构造函数注入:

    private readonly HttpContextBase _context;
    public Foo(HttpContextBase context)
    {
        _context = context;
    }
    
    public void ClearSessionState()
    {
        _context.Session["VariableName"] = null;
    }
    

    现在你可以嘲笑这个了 HttpContextBase 在单元测试中。

        2
  •  1
  •   Simone    15 年前

    在调用 StaticClass.ClearSessionState() 线。

        3
  •  1
  •   Igor Zevaka    15 年前

    您可以在生产代码中执行自己的静态“注入”,如下所示:

    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; }
        }
    }
    

    然后实际的测试变得非常简单,只需在测试之前将Context属性设置为存根实例。例如,在MOQ中,这种存根可以用一行设置:

    StaticClass.TheContext = new Mock<HttpContextBase>(){DefaultValue = DefaultValue.Mock}.Object;
    
        4
  •  0
  •   Jackson Pope    15 年前

    最后我可以把电话转到 StaticClass.ClearSessionState() 谢谢你的回答。有用的东西。