c# - 单元测试时 HttpContext.Current 为空

标签 c# unit-testing asp.net-web-api

我有以下 Web Api Controller 方法。

当我通过 Web 运行此代码时,HttpContext.Currentnever 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 始终为 null。

我该如何解决?

最佳答案

在单元测试期间,HttpContext 始终为 null,因为它通常由 IIS 填充。你有几个选择。

当然,你可以模拟 HttpContext,(你真的不应该这样做 - Don't mock HttpContext !!!! 他不喜欢被 mock ! ),.您真的应该尽量避免在整个代码中与 HttpContext 紧密耦合。尝试将其限制在一个中心区域 (SRP);

相反,弄清楚你想要实现的功能是什么,并围绕它设计一个抽象。这将使您的代码更易于测试,因为它与 HttpContext 没有紧密耦合。

根据您的示例,您希望访问 header 值。这只是一个示例,说明在使用 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;
    }
}

现在在你的 Controller 中你可以拥有你的抽象而不是与 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

    }    
}

您稍后可以注入(inject)您的具体类型以获得您想要的功能。

为了测试,您然后交换依赖项以运行您的测试。

如果被测方法是您的 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
        //.....
    }
}

关于c# - 单元测试时 HttpContext.Current 为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38170467/

相关文章:

C# WinForms 崩溃,没有异常

c# - 如何让AutoFixture从多个TypeRelay中随机选择?

python - python - 如何在python中使用nosetest/unittest断言输出?

c# - ASP.NET MVC登录客户端/ASP.NET WebAPI认证/授权服务器分离

asp.net - Request.Form 抛出异常

c# - 在 C# 中枚举时从 List<T> 中删除项目的智能方法

c# - 在 C# 中创建 Code128 条形码

javascript - 为什么我无法通过 AngularJS POST 向我的 Web Api 发送帖子?

c# - UWP XAML : Filling the screen with 2 elements, 一个 View 框

java - 如何模拟返回文件的方法