Using .NET Core 2.2, I'm trying to test a Razor Page using Identity Framework that starts like this
var user = await _userManager.GetUserAsync(User);
There are lots of solutions online that can be summed up by this generic class: setting up the UserManager on a IUserStore mock, and setting up the User on the PageContext.
public class SetupContext<T> where T : IdentityUser<Guid>, new()
{
public Mock<IUserRoleStore<T>> MockUserStore { get; private set; }
public UserManager<T> SetupUserManager()
{
MockUserStore = new Mock<IUserStore<T>>().As<IUserRoleStore<T>>();
MockUserStore.Setup(x => x.FindByIdAsync(It.IsAny<string>(), It.IsAny<CancellationToken>())).ReturnsAsync(
(string id, CancellationToken token) => new T()
{
Id = Guid.Parse(id),
UserName = "User name"
});
return new UserManager<T>(MockUserStore.Object, null, null, null, null, null, null, null, null);
}
public PageContext SetupPageContext()
{
var displayName = "User name";
var identity = new GenericIdentity(displayName);
var principle = new ClaimsPrincipal(identity);
var httpContext = new DefaultHttpContext()
{
User = principle
};
var modelState = new ModelStateDictionary();
var actionContext = new ActionContext(httpContext, new RouteData(), new PageActionDescriptor(), modelState);
var modelMetadataProvider = new EmptyModelMetadataProvider();
var viewData = new ViewDataDictionary(modelMetadataProvider, modelState);
var pageContext = new PageContext(actionContext)
{
ViewData = viewData
};
return pageContext;
}
}
The problem is that this won't work. GetUserAsync calls GetUserId which calls
principal.FindFirstValue(Options.ClaimsIdentity.UserIdClaimType)
This claim isn't setup, in fact no ID is setup anywhere, thus it can't return the user nor the user id. Then later I'll want to access database data related to UserId for testing.
I've spent quite a bit of time searching and haven't found the solution. It looks like I'm 90% there but what more do I need to set up the test correctly?
The test I'll run will be setup like this
private async Task<FreeTrialModel> SetupModelAsync()
{
_db = new RemoteHealingTechDbContext(InMemoryDbContext<RemoteHealingTechDbContext>.GetTestDbOptions());
await SeedData.Initialize(_db);
var _setup = new SetupContext<ApplicationUser>();
var userManager = _setup.SetupUserManager();
var pageContext = _setup.SetupPageContext();
return new FreeTrialModel(_db, userManager)
{
PageContext = pageContext
};
}