如何在Asp.NetCore控制器单元测试中Mock HttpResponse对象
问题原因
直接实例化控制器时,默认不会初始化ControllerContext属性,Response本质是HttpContext.Response的快捷访问属性,没有绑定HttpContext的情况下自然为null。
方法1:使用内置DefaultHttpContext实现(无需第三方Mock库)
ASP.NET Core官方提供了DefaultHttpContext类型专门用于单元测试场景,直接给控制器绑定即可:
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; // 1. 构造测试用HttpContext实例 var testHttpContext = new DefaultHttpContext(); // 2. 实例化你的控制器 var controller = new 你的控制器类名(); // 3. 给控制器绑定HttpContext controller.ControllerContext = new ControllerContext { HttpContext = testHttpContext }; // 4. 执行测试方法 var testParams = new Dictionary<string, string> { {"testKey1", "testValue1"}, {"testKey2", "testValue2"} }; var result = controller.SetCookies(testParams); // 5. 验证结果 Assert.Equal(1, result); // 也可以直接从testHttpContext中读取写入的Cookie做校验 Assert.Equal("testValue1", testHttpContext.Response.Cookies["testKey1"]);
方法2:使用Moq等Mock库模拟HttpResponse
如果你的项目已经引入了Moq这类Mock框架,也可以通过Mock对象实现:
using Moq; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; // 1. Mock响应Cookie集合 var mockCookieCollection = new Mock<IResponseCookies>(); // 2. Mock HttpResponse,关联上面的Cookie集合 var mockResponse = new Mock<HttpResponse>(); mockResponse.Setup(r => r.Cookies).Returns(mockCookieCollection.Object); // 3. Mock HttpContext,关联上面的HttpResponse var mockHttpContext = new Mock<HttpContext>(); mockHttpContext.Setup(c => c.Response).Returns(mockResponse.Object); // 4. 实例化控制器并绑定Mock的HttpContext var controller = new 你的控制器类名(); controller.ControllerContext = new ControllerContext { HttpContext = mockHttpContext.Object }; // 5. 执行测试方法 var testParams = new Dictionary<string, string> {{"testKey", "testValue"}}; var result = controller.SetCookies(testParams); // 6. 验证Cookie写入逻辑是否符合预期 mockCookieCollection.Verify(c => c.Append( "testKey", "testValue", It.Is<CookieOptions>(opt => opt.Path == "/" && opt.HttpOnly == true) ), Times.Once);
内容的提问来源于stack exchange,提问作者Rhaegar Cheng
相关产品推荐
相关产品推荐

