首页 > 解决方案 > 如何在 c# 的 api 控制器中模拟单元测试 NUnit HttpContext.Current.Request.InputStream?

问题描述

如何使用 NUnit 在 c# 中模拟 Web api 控制器请求这是我的控制器

public class SearchApiController : ApiController
{     

 [HttpPost]
    public HttpResponseMessage Applications(string authToken)
    {
        string req;
        using (var reader = new StreamReader(HttpContext.Current.Request.InputStream))
        {
            req = reader.ReadToEnd();
        }


    }   
}

我试过这样的测试用例:

            var httpRouteDataMock = new Mock<IHttpRouteData>();
            var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, "http://this.com");
            var controllerContext = new HttpControllerContext(new HttpConfiguration(), 
            httpRouteDataMock.Object, httpRequestMessage);
            _controller.ControllerContext = controllerContext;

当我使用普通的 mvc 控制器和 ControllerContext 时它工作正常

标签: c#unit-testingasp.net-web-apinunitstreamreader

解决方案


避免耦合到HttpContext.

ApiController已经有房产

HttpRequestMessage Request { get; set; }

提供对当前请求的访问。

改变设计

public class SearchApiController : ApiController  

    [HttpPost]
    public async Task<HttpResponseMessage> Applications(string authToken) {
        Stream stream = await this.Request.Content.ReadAsStreamAsync();
        string req;
        using (var reader = new StreamReader(stream)) {
            req = reader.ReadToEnd();
        }

        //...
    }   
}

现在,您原始示例中的测试关系更密切

var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, "http://this.com");
//...set the content of the request as needed
httpRequestMessage.Content = new StringContent("some data");

var httpRouteDataMock = new Mock<IHttpRouteData>();
var controllerContext = new HttpControllerContext(new HttpConfiguration(), 
    httpRouteDataMock.Object, httpRequestMessage);
_controller.ControllerContext = controllerContext;

//...

推荐阅读