这是我的问题。我似乎无法创建需要已认证用户的集成测试。我使用
这也包括:
这些基于https://gunnarpeipman.com/aspnet-core-integration-tests-users-roles/主题。尽管我没有使用他在之前线程中指出的
这是我在控制器中的操作方法:
从调试测试的结果来看,响应重定向到
Microsoft.AspNetCore.Mvc.Testing
进行测试。以下是我的测试:
如您所见,客户端拥有“患者”角色和一个用户ID。以下是我的助手:
public class TestClaimsProvider
{
public IList<Claim> Claims { get; }
public TestClaimsProvider(IList<Claim> claims)
{
Claims = claims;
}
public TestClaimsProvider()
{
Claims = new List<Claim>();
}
public static TestClaimsProvider WithAdminClaims()
{
var provider = new TestClaimsProvider();
provider.Claims.Add(new Claim(ClaimTypes.NameIdentifier, Guid.NewGuid().ToString()));
provider.Claims.Add(new Claim(ClaimTypes.Name, "Admin user"));
provider.Claims.Add(new Claim(ClaimTypes.Role, "Administrator"));
return provider;
}
public static TestClaimsProvider WithUserClaims()
{
var provider = new TestClaimsProvider();
provider.Claims.Add(new Claim(ClaimTypes.NameIdentifier, Guid.NewGuid().ToString()));
provider.Claims.Add(new Claim(ClaimTypes.Name, "Patient"));
provider.Claims.Add(new Claim(ClaimTypes.Role, "Patient"));
return provider;
}
}
这也包括:
public class TestAuthHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{
private readonly IList<Claim> _claims;
public TestAuthHandler(IOptionsMonitor<AuthenticationSchemeOptions> options,
ILoggerFactory logger,
UrlEncoder encoder,
ISystemClock clock, TestClaimsProvider claimsProvider) : base(options, logger, encoder, clock)
{
_claims = claimsProvider.Claims;
}
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
{
var identity = new ClaimsIdentity(_claims, "Test");
var principal = new ClaimsPrincipal(identity);
var ticket = new AuthenticationTicket(principal, "Test");
var result = AuthenticateResult.Success(ticket);
return Task.FromResult(result);
}
}
而且:
public static class WebApplicationFactoryExtensions
{
public static WebApplicationFactory<T> WithAuthentication<T>(this WebApplicationFactory<T> factory, TestClaimsProvider claimsProvider) where T : class
{
return factory.WithWebHostBuilder(builder =>
{
builder.ConfigureTestServices(services =>
{
services.AddAuthentication("Test")
.AddScheme<AuthenticationSchemeOptions, TestAuthHandler>("Test", op => { });
services.AddScoped<TestClaimsProvider>(_ => claimsProvider);
});
});
}
public static HttpClient CreateClientWithTestAuth<T>(this WebApplicationFactory<T> factory, TestClaimsProvider claimsProvider) where T : class
{
var client = factory.WithAuthentication(claimsProvider).CreateClient(new WebApplicationFactoryClientOptions
{
AllowAutoRedirect = false
});
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Test");
return client;
}
这些基于https://gunnarpeipman.com/aspnet-core-integration-tests-users-roles/主题。尽管我没有使用他在之前线程中指出的
FakeStartup
类,但是我已经尝试了这里https://learn.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-6.0#customize-the-client-with-withwebhostbuilder文档中的身份验证,但是结果相同。这是我在控制器中的操作方法:
[Authorize(Roles = PatientRoleName)]
public async Task<IActionResult> MakePatientAppointment()
{
var patient = await this.patientService.GetPatientByUserIdAsync(this.User.GetId());
if (string.IsNullOrWhiteSpace(patient.FirstName) ||
string.IsNullOrWhiteSpace(patient.LastName) ||
string.IsNullOrWhiteSpace(patient.Phone))
{
this.TempData["Message"] = PatientProfileIsNotFinishedMsg;
return RedirectToAction("Finish", "Patient", new { area = "" });
}
var viewModel = new PatientAppointmentCreateModel
{
DoctorId = await this.doctorService.GetDoctorId(),
AppointmentCauses = await this.appointmentCauseService.GetAllCauses()
};
return View(viewModel);
}
从调试测试的结果来看,响应重定向到
/Identity/Login
,因此我理解用户尚未登录。我该如何重构代码以使用户得到认证?