我有Web Api controller Action method
我正在尝试进行单元测试。我有一个自定义过滤器,它在该动作控制器之前运行。
我对自定义操作过滤器中使用的HttpContext.Current.User.Identity.Name
有疑问。
当我从网络客户端发送我的http发布请求时,它很有效。
但是,当我从单位测试发送http post请求时,HttpContext.Current
总是抱怨null
不要了解哪里出了什么问题。 有人可以解释一下吗?
请请注意,我在here看到了答案,但我不确定在我的案例中需要添加该代码的位置。
答案 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
。例如FakeItEasy
(https://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
}
}