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

发布于 2024-10-04 04:13:40 字数 569 浏览 6 评论 0原文

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

I've got a method which I've added unit tests for in a C#/ASP.Net web project. The method has been modified by someone else to include a call to a static method on a class which wraps an HttpContext (to add some session state), but during testing I don't have an HttpContext, so this throws a null reference exception. Any ideas how to get round this problem? I don't want to make too many changes to production code if I can help it.

Method under test:

public int MethodUnderTest() 
{
    ...
    // Added line which breaks the tests
    StaticClass.ClearSessionState();
}

In StaticClass:

public void ClearSessionState()
{
    HttpContext.Current.Session["VariableName"] = null;
}

This throws a NullReferenceException because HttpContext.Current is null during testing.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

情痴 2024-10-11 04:13:40

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

private readonly HttpContextBase _context;
public Foo(HttpContextBase context)
{
    _context = context;
}

public void ClearSessionState()
{
    _context.Session["VariableName"] = null;
}

现在您可以模拟此 HttpContextBase”。

You are pretty much in a dead end here as far as unit testing methods that use HttpContext.Current are concerned. The proper way would be to modify this code to use constructor injection:

private readonly HttpContextBase _context;
public Foo(HttpContextBase context)
{
    _context = context;
}

public void ClearSessionState()
{
    _context.Session["VariableName"] = null;
}

Now you can mock this HttpContextBase in your unit test.

你曾走过我的故事 2024-10-11 04:13:40

您可以在调用 StaticClass.ClearSessionState() 行之前使用模拟/存根对象设置 HttpContext.Current。

You could set HttpContext.Current with a mock/stub object before invoking the StaticClass.ClearSessionState() line.

无声静候 2024-10-11 04:13:40

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

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;

You could do your own static "injection" in the production code like so:

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

The actual test then becomes pretty trivial, simply set TheContext property to a stub instance before the test. For example in Moq such stub could be set up with one line:

StaticClass.TheContext = new Mock<HttpContextBase>(){DefaultValue = DefaultValue.Mock}.Object;
攒眉千度 2024-10-11 04:13:40

最后,我可以删除对 StaticClass.ClearSessionState() 的调用,但感谢您的所有答案。有用的东西。

In the end I could just remove the call to StaticClass.ClearSessionState(), but thanks for all the answers. Useful stuff.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文