Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock out the UserManager in ASP.NET 5

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?

like image 728
hally9k Avatar asked Dec 20 '15 18:12

hally9k


1 Answers

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.

like image 93
GeorgDangl Avatar answered Nov 03 '22 02:11

GeorgDangl