从单元测试发送请求时,HttpContext.Current始终为null

时间:2016-05-01 09:44:30

标签: unit-testing asp.net-web-api httpcontext

我有Web Api controller Action method我正在尝试进行单元测试。我有一个自定义过滤器,它在该动作控制器之前运行。

我对自定义操作过滤器中使用的HttpContext.Current.User.Identity.Name有疑问。

当我从网络客户端发送我的http发布请求时,它很有效。

但是,当我从单位测试发送http post请求时,HttpContext.Current总是抱怨null

不要了解哪里出了什么问题。 有人可以解释一下吗?

请注意,我在here看到了答案,但我不确定在我的案例中需要添加该代码的位置。

2 个答案:

答案 0 :(得分:1)

单元测试与通过Web客户端调用api不同。

当您使用Web客户端时,您的api正在您的Web服务器(例如IIS)的上下文中运行,并且Web服务器将为系统提供che" current" HttpContext

如果您从单元测试方法中调用简单明了的代码,那么您不会在Web服务器的上下文中运行,但您只是将其称为类的方法。显然你可以做到,但你需要" 模拟" (假的,如果你愿意的话)当前HttpContext模拟你在真实的网络服务器上运行。

请查看此SO答案,了解有关如何操作的详细信息。

顺便说一下,当您运行集成测试时(通过Web客户端调用真正的API并只检查输入输出结果),情况并非如此:在这种情况下,您将在真实环境中运行您的实际代码会很好。

答案 1 :(得分:0)

HttpContext.Current未在测试中的自托管方案中设置。

但是,您可以在HttpContext.Current周围创建一个包装器,并在运行测试之前填充它。像这样:

public static class CurrentHttpContext
{
    public static Func<HttpContextBase> Instance = () => new HttpContextWrapper(HttpContext.Current);
}

然后在测试中设置HttpSelfHostServer的地方,填充CurrentHttpContext.Instance。例如FakeItEasyhttps://github.com/FakeItEasy/FakeItEasy):

var context = A.Fake<HttpContextBase>();
CurrentHttpContext.Instance = () => context;

然后,您可以在过滤器中访问CurrentHttpContext.Instance而不是HttpContext.Current

public class MyAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var context = CurrentHttpContext.Instance();
        // stuff
    }
}