How to mock UserManager in .Net Core testing?

I know this is months old but I keep getting back to this thread. I will extend my own answer on this topic because just pointing to Haok’s GitHub example is like saying: “Read a book” as it is huge. It does not pinpoint the issue and what you need to do. You need to isolate a Mock object, but not only that but also you need to ‘Setup’ the method for ‘CreateAsync’. So let’s put this in three parts:

  1. You need to MOCK if you are using MOQ or a similar framework to make a mocked up creation of the UserManager.
  2. You need to Setup the methods of UserManager you expect to get results back from.
  3. Optionally you would want to inject some generic list from a mocked Entity Framework Core 2.1 or similar so that you can actually see that a list of IDentity Users actually increases or decreases. Not just that UserManager succeeded and nothing else

So say I have a helper method for returning a Mocked UserManager. Which is just slightly altered from the Haok code:

public static Mock<UserManager<TUser>> MockUserManager<TUser>(List<TUser> ls) where TUser : class
{
    var store = new Mock<IUserStore<TUser>>();
    var mgr = new Mock<UserManager<TUser>>(store.Object, null, null, null, null, null, null, null, null);
    mgr.Object.UserValidators.Add(new UserValidator<TUser>());
    mgr.Object.PasswordValidators.Add(new PasswordValidator<TUser>());

    mgr.Setup(x => x.DeleteAsync(It.IsAny<TUser>())).ReturnsAsync(IdentityResult.Success);
    mgr.Setup(x => x.CreateAsync(It.IsAny<TUser>(), It.IsAny<string>())).ReturnsAsync(IdentityResult.Success).Callback<TUser, string>((x, y) => ls.Add(x));
    mgr.Setup(x => x.UpdateAsync(It.IsAny<TUser>())).ReturnsAsync(IdentityResult.Success);

    return mgr;
}

What is key to this is I am injecting a generic ‘TUser’ that is what I will be testing as well injecting a list of this. Similar to my example of:

 private List<ApplicationUser> _users = new List<ApplicationUser>
 {
      new ApplicationUser("User1", "user1@bv.com") { Id = 1 },
      new ApplicationUser("User2", "user2@bv.com") { Id = 2 }
 };
    
 ...

 private _userManager = MockUserManager<ApplicationUser>(_users).Object; 

Then finally I am testing a pattern with a repository similar to this implementation I want to test:

 public async Task<int> CreateUser(ApplicationUser user, string password) => (await _userManager.CreateAsync(user, password)).Succeeded ? user.Id : -1;

I test it like this:

 [Fact]
 public async Task CreateAUser()
 {
      var newUser = new ApplicationUser("NewUser", "New@test.com");
      var password = "P@ssw0rd!";

      var result = await CreateUser(newUser, password);

      Assert.Equal(3, _users.Count);
  }

The key to what I did is that not only did I ‘Setup’ the CreateAsync but I provided a callback so I can actually see my list I inject get incremented. Hope this helps someone.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)