如何Mock User.Identity.Name 完成Controller控制器方法单元测试
你可以通过为控制器注入伪造的用户上下文,来模拟User.Identity.Name的取值,无需额外依赖,直接使用ASP.NET Core内置的身份类即可实现,修改后的测试代码如下:
[Fact] public void CheckPublicIDIsEmpty() { Mock<IRepository> mock = new Mock<IRepository>(); // 此处第二个参数需和后续伪造的用户名保持一致 mock.Setup(r => r.CheckCardName("TestID", "TestName")).Returns(false); // 构造伪造的身份信息,第一个参数即为User.Identity.Name的返回值 var fakeIdentity = new GenericIdentity("TestName"); var fakePrincipal = new GenericPrincipal(fakeIdentity, null); CardController cardController = new CardController(mock.Object); // 为控制器赋值伪造的Http上下文 cardController.ControllerContext = new ControllerContext() { HttpContext = new DefaultHttpContext() { User = fakePrincipal } }; var result = cardController.CheckPublicID("TestID"); // 调整断言:验证返回值类型为JsonResult var jsonResult = Assert.IsType<JsonResult>(result); // 验证返回的布尔值与Mock预设的返回值一致 Assert.False(Convert.ToBoolean(jsonResult.Value)); }
可选方案:使用Moq模拟身份对象
如果你更倾向于全Mock实现,可以用以下代码替换身份构造部分,效果完全一致:
var mockIdentity = new Mock<IIdentity>(); mockIdentity.Setup(i => i.Name).Returns("TestName"); // 如果你的逻辑需要判断用户登录状态,需额外模拟IsAuthenticated属性 mockIdentity.Setup(i => i.IsAuthenticated).Returns(true); var mockPrincipal = new Mock<ClaimsPrincipal>(); mockPrincipal.Setup(p => p.Identity).Returns(mockIdentity.Object); cardController.ControllerContext = new ControllerContext() { HttpContext = new DefaultHttpContext() { User = mockPrincipal.Object } };
注意事项
- 构造伪造身份时的用户名,需要和你Mock
IRepository.CheckCardName方法时传入的第二个参数保持一致,才能匹配到预设的返回值 - 如果你的业务逻辑会校验用户是否已登录,必须给
IIdentity.IsAuthenticated赋值为true,否则会出现逻辑判断异常
内容的提问来源于stack exchange,提问作者SLAYER
相关产品推荐
相关产品推荐

