模拟 Razor Pages 单元测试的 User ClaimsPrincipal
Mocking User ClaimsPrincipal for Razor Pages Unit Test
我遇到了有关为结合了 MVVM 的 Razor 页面编写单元测试的问题。我想测试 Razor 中的 OnPostAsync()
方法,但是此方法将调用另外两个需要 ClaimsPrincipal
用户的方法。但是,我不能在我的测试中将 User
作为这些方法的参数。
我目前的测试方法:
[Test]
public void MakeBookingTest()
{
//Arrange
var optionsbuilder = new DbContextOptionsBuilder<ApplicationDbContext>();
optionsbuilder.UseInMemoryDatabase(databaseName: "TeacherDB");
var _dbContext = new ApplicationDbContext(optionsbuilder.Options);
JsonResult json = new JsonResult(true);
_dbContext.ImportOption.Add(new ImportOption { Id = 1, isUnique = 1, Option = "Teacher" });
_dbContext.SaveChanges();
var mockedUserManager = GetMockUserManager();
var mockedCalendar = new Mock<ICalendarService>();
Booking booking = new Booking {
EventId = "2",
ClassroomId = 3,
BeginTime = DateTime.Now,
EndTime = DateTime.Now,
Description = "fjdkafjal",
Summary = "Test01" };
mockedCalendar.Setup(x => x.CreateEvent(booking, "2", "0863629@hr.nl", false)).Returns("111");
var mockedRoleManager = GetMockRoleManager();
var model = new MakeBookingModel(_dbContext, mockedUserManager.Object, mockedCalendar.Object, mockedRoleManager.Object);
//var controllerContext = new Mock<ControllerContext>();
var result = model.OnPostAsync();
}
我要测试的方法:
[ValidateAntiForgeryToken]
public async Task<IActionResult> OnPostAsync()
{
CurrentRole = await _validation.GetCurrentRole(User);
CurrentUser = await _userManager.GetUserAsync(User);
//(rest of the code...)
_validation.GetCurrentRole
方法:
public async Task<string> GetCurrentRole(ClaimsPrincipal User)
{
ApplicationUser currentUser = await _userManager.GetUserAsync(User);
Task<IList<string>> rolesUser = _userManager.GetRolesAsync(currentUser);
return rolesUser.Result.First();
}
我似乎无法使 OnPostAsync
/GetCurrentRole
中的 User
不为 null。
如何将 User
分配给这些方法?
通过 PageModel
的 PageContext
的一部分的 HTTP 上下文设置 User
// Arrange
//...code removed for brevity
//Create test user
var displayName = "User name";
var identity = new GenericIdentity(displayName);
var principle = new ClaimsPrincipal(identity);
// use default context with user
var httpContext = new DefaultHttpContext() {
User = principle
}
//need these as well for the page context
var modelState = new ModelStateDictionary();
var actionContext = new ActionContext(httpContext, new RouteData(), new PageActionDescriptor(), modelState);
var modelMetadataProvider = new EmptyModelMetadataProvider();
var viewData = new ViewDataDictionary(modelMetadataProvider, modelState);
// need page context for the page model
var pageContext = new PageContext(actionContext) {
ViewData = viewData
};
//create model with necessary dependencies
var model = new MakeBookingModel(_dbContext, mockedUserManager.Object, mockedCalendar.Object, mockedRoleManager.Object) {
PageContext = pageContext
};
//Act
//...
引用Razor Pages unit tests in ASP.NET Core
您混合了 .Result
这样的异步调用和阻塞调用,这导致了 GetCurrentRole
.
中的死锁
一直重构为异步
public async Task<string> GetCurrentRole(ClaimsPrincipal User) {
ApplicationUser currentUser = await _userManager.GetUserAsync(User);
var rolesUser = await _userManager.GetRolesAsync(currentUser);
return rolesUser.FirstOrDefault();
}
我遇到了有关为结合了 MVVM 的 Razor 页面编写单元测试的问题。我想测试 Razor 中的 OnPostAsync()
方法,但是此方法将调用另外两个需要 ClaimsPrincipal
用户的方法。但是,我不能在我的测试中将 User
作为这些方法的参数。
我目前的测试方法:
[Test]
public void MakeBookingTest()
{
//Arrange
var optionsbuilder = new DbContextOptionsBuilder<ApplicationDbContext>();
optionsbuilder.UseInMemoryDatabase(databaseName: "TeacherDB");
var _dbContext = new ApplicationDbContext(optionsbuilder.Options);
JsonResult json = new JsonResult(true);
_dbContext.ImportOption.Add(new ImportOption { Id = 1, isUnique = 1, Option = "Teacher" });
_dbContext.SaveChanges();
var mockedUserManager = GetMockUserManager();
var mockedCalendar = new Mock<ICalendarService>();
Booking booking = new Booking {
EventId = "2",
ClassroomId = 3,
BeginTime = DateTime.Now,
EndTime = DateTime.Now,
Description = "fjdkafjal",
Summary = "Test01" };
mockedCalendar.Setup(x => x.CreateEvent(booking, "2", "0863629@hr.nl", false)).Returns("111");
var mockedRoleManager = GetMockRoleManager();
var model = new MakeBookingModel(_dbContext, mockedUserManager.Object, mockedCalendar.Object, mockedRoleManager.Object);
//var controllerContext = new Mock<ControllerContext>();
var result = model.OnPostAsync();
}
我要测试的方法:
[ValidateAntiForgeryToken]
public async Task<IActionResult> OnPostAsync()
{
CurrentRole = await _validation.GetCurrentRole(User);
CurrentUser = await _userManager.GetUserAsync(User);
//(rest of the code...)
_validation.GetCurrentRole
方法:
public async Task<string> GetCurrentRole(ClaimsPrincipal User)
{
ApplicationUser currentUser = await _userManager.GetUserAsync(User);
Task<IList<string>> rolesUser = _userManager.GetRolesAsync(currentUser);
return rolesUser.Result.First();
}
我似乎无法使 OnPostAsync
/GetCurrentRole
中的 User
不为 null。
如何将 User
分配给这些方法?
通过 PageModel
的 PageContext
User
// Arrange
//...code removed for brevity
//Create test user
var displayName = "User name";
var identity = new GenericIdentity(displayName);
var principle = new ClaimsPrincipal(identity);
// use default context with user
var httpContext = new DefaultHttpContext() {
User = principle
}
//need these as well for the page context
var modelState = new ModelStateDictionary();
var actionContext = new ActionContext(httpContext, new RouteData(), new PageActionDescriptor(), modelState);
var modelMetadataProvider = new EmptyModelMetadataProvider();
var viewData = new ViewDataDictionary(modelMetadataProvider, modelState);
// need page context for the page model
var pageContext = new PageContext(actionContext) {
ViewData = viewData
};
//create model with necessary dependencies
var model = new MakeBookingModel(_dbContext, mockedUserManager.Object, mockedCalendar.Object, mockedRoleManager.Object) {
PageContext = pageContext
};
//Act
//...
引用Razor Pages unit tests in ASP.NET Core
您混合了 .Result
这样的异步调用和阻塞调用,这导致了 GetCurrentRole
.
一直重构为异步
public async Task<string> GetCurrentRole(ClaimsPrincipal User) {
ApplicationUser currentUser = await _userManager.GetUserAsync(User);
var rolesUser = await _userManager.GetRolesAsync(currentUser);
return rolesUser.FirstOrDefault();
}