我在此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);
使用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()