我有以下网络Api控制器方法。
当我通过网络运行此代码时,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.
我该如何解决?
答案 0 :(得分:18)
在单元测试期间,HttpContext
始终为null
,因为它通常由IIS填充。你有几个选择。
当然,你可以嘲笑HttpContext
,(你不应该这么做 - Don't mock 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()
方法,您可以创建假依赖项或使用模拟框架
[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
//.....
}
}
答案 1 :(得分:5)
这是设计使然,它始终为空。但是 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
希望这会有所帮助:)
答案 2 :(得分:1)
我添加了FakeHttpContext nuget包,它对我有用。
答案 3 :(得分:1)
您可以尝试添加FakeHttpContext nuget包。
答案 4 :(得分:-1)
你需要的只是
controller.Request = new HttpRequestMessage();
controller.Configuration = new HttpConfiguration();