HttpContext.单元测试时Current为null
本文关键字:null Current 单元测试 HttpContext | 更新日期: 2023-09-27 17:54:08
我有以下web Api控制器方法。
当我通过web运行此代码时,HttpContext.Current
为never null
,并给出期望的值。
public override void Post([FromBody]TestDTO model)
{
var request = HttpContext.Current.Request;
var testName = request.Headers.GetValues("OS Type")[0];
// more code
}
然而,当我从Unit Test
调用这个方法时,HttpContext.Current is always null.
我如何修复它?
在单元测试期间,HttpContext
总是null
,因为它通常由IIS填充。你有几个选择。
当然,您可以模拟HttpContext
,(您不应该真正这样做- 不要模拟HttpContext!!!!他不喜欢被嘲笑!您应该尽量避免在代码中使用HttpContext
进行紧密耦合。尝试将其限制在一个中心区域(SRP);
相反,弄清楚你想要实现的功能是什么,并围绕它设计一个抽象。这将允许您的代码更具可测试性,因为它不那么紧密地耦合到HttpContext
。
根据您的示例,您正在寻找访问头值。这只是一个关于如何在使用HttpContext
时改变你的想法的例子。
你原来的例子有这个
var request = HttpContext.Current.Request;
var testName = request.Headers.GetValues("OS Type")[0];
当你在寻找这样的东西
var testName = myService.GetOsType();
然后创建一个服务来提供
public interface IHeaderService {
string GetOsType();
}
可以有像
这样的具体实现public class MyHeaderService : IHeaderService {
public string GetOsType() {
var request = HttpContext.Current.Request;
var testName = request.Headers.GetValues("OS Type")[0];
return testName;
}
}
现在在你的控制器中你可以有你的抽象而不是与HttpContext
紧密耦合
public class MyApiController : ApiController {
IHeaderService myservice;
public MyApiController(IHeaderService headers) {
myservice = headers;
}
public IHttpActionResult Post([FromBody]TestDTO model) {
var testName = myService.GetOsType();
// more code
}
}
可以稍后注入具体类型以获得所需的功能。
对于测试,然后交换依赖项来运行测试。
如果被测试的方法是你的Post()
方法,你可以创建一个假的依赖或者使用一个mock框架
[TestClass]
public class MyTestClass {
public class MyFakeHeaderService : IHeaderService {
string os;
public MyFakeHeaderService(string os) {
this.os = os;
}
public string GetOsType() {
return os;
}
}
[TestMethod]
public void TestPostMethod() {
//Arrange
IHeaderService headers = new MyFakeHeaderService("FAKE OS TYPE");
var sut = new MyApiController(headers);
var model = new TestDTO();
//Act
sut.Post(model);
//Assert
//.....
}
}
这是设计的,它总是空的。但是在Nuget上有一个
FakeHttpContext
项目,你可以简单地使用它。
要安装FakeHttpContext,在包管理控制台(PMC)中运行以下命令
Install-Package FakeHttpContext
然后像这样使用:
using (new FakeHttpContext())
{
HttpContext.Current.Session["mySession"] = "This is a test";
}
访问https://www.nuget.org/packages/FakeHttpContext安装包
参见Github上的示例:https://github.com/vadimzozulya/FakeHttpContext#examples
希望对你有帮助
你所需要的是
controller.Request = new HttpRequestMessage();
controller.Configuration = new HttpConfiguration();
从unit-testing-controllers-in-web-api