I am writing a UI for managing users in an ASP.NET 5
app. I need to show any errors returned by the UserManager in the UI. I have the IdentityResult
errors being passed back in the view model but I am a touch adrift when it comes to testing my code.
What is the best way to Mock the UserManager
in ASP.NET 5
?
Should I be inheriting from UserManager
and overriding all the methods I am using and then injecting my version of UserManager
into an instance of the Controller
in my test project?
I have managed it with the help of the MVC Music Store sample application.
In my Unit Test class, I set up the database context and UserManager like this:
public class DatabaseSetupTests : IDisposable
{
private MyDbContext Context { get; }
private UserManager<ApplicationUser> UserManager { get; }
public DatabaseSetupTests()
{
var services = new ServiceCollection();
services.AddEntityFramework()
.AddInMemoryDatabase()
.AddDbContext<MyDbContext>(options => options.UseInMemoryDatabase());
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<MyDbContext>();
// Taken from https://github.com/aspnet/MusicStore/blob/dev/test/MusicStore.Test/ManageControllerTest.cs (and modified)
// IHttpContextAccessor is required for SignInManager, and UserManager
var context = new DefaultHttpContext();
context.Features.Set<IHttpAuthenticationFeature>(new HttpAuthenticationFeature());
services.AddSingleton<IHttpContextAccessor>(h => new HttpContextAccessor { HttpContext = context });
var serviceProvider = services.BuildServiceProvider();
Context = serviceProvider.GetRequiredService<MyDbContext>();
UserManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
}
....
}
Then I can use the UserManager in my unit tests, for example:
[Fact]
public async Task DontCreateAdminUserWhenOtherAdminsPresent()
{
await UserManager.CreateAsync(new ApplicationUser { UserName = "[email protected]" }, "IDoComplyWithTheRules2016!");
...
}
If your Dependency Injector is not able to resolve an IHttpContextAccessor then you will not be able to create a UserManager instance due to it being dependent on it. I think (and this is just an assumption), that with Asp.Net 5, the UserManager does take care of refreshing cookie based claims when you change them (claims, roles...) for a user and therefore requires some HttpContext for login / logout actions and cookie access.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With