如何模拟IdentityUser使signInManager.IsSignedIn(User)返回true
模拟登录状态测试Razor页面登录后效果
你现在已经通过ConfigureTestServices替换了仓储实现并添加了Identity服务,要让signInManager.IsSignedIn(User)返回true,有两种实用方法:
方法一:直接模拟SignInManager的返回值
用Moq框架给SignInManager<IdentityUser>做个模拟,让它的IsSignedIn方法直接返回true即可:
先确保项目安装了Moq NuGet包,然后修改你的配置代码:
builder.ConfigureTestServices(services => { // 保留你原有的仓储替换代码 services.AddScoped<ITextPostRepository, TestTextPostRepository>(sp => new TestTextPostRepository(textPosts)); services.AddScoped<ITagRepository, TestTagRepository>(sp => new TestTagRepository(tags)); // 替换默认SignInManager为模拟对象 services.RemoveAll<SignInManager<IdentityUser>>(); var mockSignInManager = new Mock<SignInManager<IdentityUser>>( Mock.Of<UserManager<IdentityUser>>(x => x.Options == new IdentityOptions()), Mock.Of<IHttpContextAccessor>(), Mock.Of<IUserClaimsPrincipalFactory<IdentityUser>>(), null, null, null, null); // 配置IsSignedIn方法始终返回true mockSignInManager.Setup(m => m.IsSignedIn(It.IsAny<ClaimsPrincipal>())).Returns(true); services.AddScoped(_ => mockSignInManager.Object); });
这种方式无需构造真实认证上下文,适合快速验证视图的登录后展示逻辑。
方法二:构造真实的已认证用户上下文
如果视图需要用到用户的具体信息(如用户名、ID),可以构造一个已认证的用户身份,让HttpContext持有它:
builder.ConfigureTestServices(services => { // 保留原有的仓储替换代码 services.AddScoped<ITextPostRepository, TestTextPostRepository>(sp => new TestTextPostRepository(textPosts)); services.AddScoped<ITagRepository, TestTagRepository>(sp => new TestTagRepository(tags)); // 配置Identity并替换HttpContextAccessor services.AddIdentity<IdentityUser, IdentityRole>(); services.AddScoped<IHttpContextAccessor>(sp => { var httpContext = new DefaultHttpContext(); // 构造已认证用户身份 var claims = new List<Claim> { new Claim(ClaimTypes.NameIdentifier, "test-user-123"), new Claim(ClaimTypes.Name, "测试用户") }; var identity = new ClaimsIdentity(claims, "TestAuth"); httpContext.User = new ClaimsPrincipal(identity); return new HttpContextAccessor { HttpContext = httpContext }; }); });
配置完成后,SignInManager.IsSignedIn(User)会识别到已认证用户并返回true,同时视图也能获取到用户的Claims信息。
另外,如果是用WebApplicationFactory创建客户端后发起请求,还可以给请求添加认证Cookie,模拟真实登录流程:
var client = builder.CreateClient(); // 构造认证信息 var claims = new List<Claim> { new Claim(ClaimTypes.NameIdentifier, "test-user-123") }; var identity = new ClaimsIdentity(claims, "Identity.Application"); var principal = new ClaimsPrincipal(identity); var authProperties = new AuthenticationProperties(); // 生成认证Cookie var sp = builder.Services.BuildServiceProvider(); var authService = sp.GetRequiredService<IAuthenticationService>(); var mockResponse = new Mock<HttpResponse>(); await authService.SignInAsync( new DefaultHttpContext { Response = mockResponse.Object }, "Identity.Application", principal, authProperties); // 将Cookie添加到客户端请求头 var cookie = mockResponse.Object.Headers["Set-Cookie"].First(); client.DefaultRequestHeaders.Add("Cookie", cookie);
这种方式适合测试从请求到视图的完整交互流程。
内容的提问来源于stack exchange,提问作者mathdx
相关产品推荐
相关产品推荐

