[在动作内部分配了Response属性时的单元测试控制器动作

问题描述 投票:0回答:1

我在此post中看到了非常相同的问题,但现在ASP.Net Core 2.2中都没有解决方案。当我调试单元测试时,Response属性仍然为null,因此测试失败。我一直在阅读asp.net核心文档,以获取有关如何模拟ControllerContext的答案,以便Response属性具有值,但我找不到任何有效的方法。

这里是造成麻烦的动作中的一行:

Response.Headers.Add("Access-Control-Expose-Headers", "Content-Range");

所以我最终在单元测试设置中是:

        var routeData = new RouteData();
        routeData.Values.Add("controller", "Home");

        var headerDictionary = new HeaderDictionary();
        var response = new Mock<HttpResponse>();
        response.SetupGet(r => r.Headers).Returns(headerDictionary);

        var httpContext = new Mock<HttpContext>();
        httpContext.SetupGet(a => a.Response).Returns(response.Object);

        var actionContext = new ActionContext(
            httpContext.Object,
            routeData, 
            new ControllerActionDescriptor());

        _controller.ControllerContext = new ControllerContext(actionContext);
c# unit-testing asp.net-core asp.net-web-api asp.net-core-2.2
1个回答
0
投票

使用DefaultHttpContext可以避免很多设置,因为它会已经填充了所需的属性。这包括Response及其成员

//..

var routeData = new RouteData();
routeData.Values.Add("controller", "Home");

var httpContext = DefaultHttpContext(); //<--

var actionContext = new ActionContext(
    httpContext,
    routeData, 
    new ControllerActionDescriptor());

_controller.ControllerContext = new ControllerContext(actionContext);

//...

在锻炼了被测对象之后,可以从控制器使用的上下文中获得响应,并声明所期望的行为。

//...

//Assert
var response = httpContext.Response;
var key = "Access-Control-Expose-Headers";
Assert.True(response.Headers.TryGetValues(key, out var value));
Assert.Equals("Content-Range", value.FirstOrDefault()
© www.soinside.com 2019 - 2024. All rights reserved.