ASP.NET控制器单元测试失败,默认Response属性为null如何解决?
你手动实例化Controller时,ASP.NET Core运行时不会自动为其填充HttpContext上下文对象,Controller的Response属性本质是HttpContext.Response的快捷访问,未赋值HttpContext时自然为null。
解决方案
你只需要在初始化控制器实例后,手动为其赋值ControllerContext,传入预置的HttpContext对象即可,不需要Mock框架也能实现。
方法1:使用内置DefaultHttpContext(推荐,无额外依赖)
修改你的InitSut方法如下:
protected override void InitSut() { _sut = new SomeController(_mockedLogger, _mockedService, _mockedRepository, _mockedHtmlSanitizer); // 手动赋值上下文,内置DefaultHttpContext会自动初始化Response、Request等属性 _sut.ControllerContext = new ControllerContext { HttpContext = new DefaultHttpContext() }; }
完成上述修改后,业务代码中访问Response.Headers就不会再触发空引用异常。如果需要验证响应头是否正确写入,也可以直接通过_sut.Response.Headers取值做断言。
方法2:使用Moq模拟HttpContext(适合需要定制上下文行为的场景)
如果你的测试逻辑需要对HttpContext的其他行为做模拟,可以用Moq框架构造模拟对象:
protected override void InitSut() { _sut = new SomeController(_mockedLogger, _mockedService, _mockedRepository, _mockedHtmlSanitizer); var headerDictionary = new HeaderDictionary(); var mockResponse = new Mock<HttpResponse>(); mockResponse.Setup(r => r.Headers).Returns(headerDictionary); var mockHttpContext = new Mock<HttpContext>(); mockHttpContext.Setup(c => c.Response).Returns(mockResponse.Object); _sut.ControllerContext = new ControllerContext { HttpContext = mockHttpContext.Object }; }
补充说明
你之前参考的是.NET Framework版本ASP.NET Web API的测试文档,和你当前使用的ASP.NET Core Controller体系不兼容,因此无法解决问题。
内容的提问来源于stack exchange,提问作者Zenith
相关产品推荐
相关产品推荐

