unit testing时HttpContext.Current为null
我有以下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.
我如何解决它?
在unit testing期间, HttpContext
始终为null
因为它通常由IIS填充。 你有几个选择。
当然,你可以模拟HttpContext
,(你不应该真的这样做 – 不要模仿HttpContext !!!!他不喜欢被嘲笑!),. 你应该尝试远离代码中与HttpContext
紧密耦合。 尝试将其约束到一个中心区域(SRP);
而是弄清楚你想要实现的function是什么,并围绕它设计一个抽象。 这将允许您的代码更加可测试,因为它与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 } }
您可以稍后注入具体类型以获得所需的function。
为了测试你然后交换依赖项来运行你的测试。
如果测试中的方法是Post()
方法,则可以创建伪依赖项或使用模拟框架
[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 //..... } }
这是设计的,它总是空的。 但是
FakeHttpContext
上有一个FakeHttpContext
项目,只需你可以使用它。
要安装FakeHttpContext,请在程序包管理器控制台(PMC)中运行以下命令
Install-Package FakeHttpContext
然后像这样使用它:
using (new FakeHttpContext()) { HttpContext.Current.Session["mySession"] = "This is a test"; }
访问https://www.nuget.org/packages/FakeHttpContext/
希望这会有所帮助:)
我添加了FakeHttpContext nuget包,它对我有用。
所有你需要的是
controller.Request = new HttpRequestMessage(); controller.Configuration = new HttpConfiguration();
来自unit-testing-controllers-in-web-api
- 为什么Http请求Fiddler的速度非常快
- ‘System.Data.Entity.Migrations.DbMigrationsConfiguration`1’的类型初始值设定项引发exception
- 如何在Web API中实现HttpMessageHandler?
- 使用WebAPI HttpResponseMessage时下载文件提示
- 尝试使用.netstandard 2程序集时,Web Api 2运行时错误
- 如何使用自定义属性扩展IdentityUser
- 使用ASP.Net MVC 4 Web API和Ninject.Web.WebApi发布问题
- Route属性中的正则表达式 – RESTful API ASP.NET Web API
- ASP.NET中的HostingEnvironment.QueueBackgroundWorkItem()用于小型后台任务
- 批量请求 – Dynamics CRM
- 在asp .Net Core项目中添加wsdl web引用