Search code examples
c#unit-testingasp.net-coremoqxunit

Mocking issue: Can not instantiate proxy of class: Microsoft.AspNetCore.Identity.UserManager`


I am trying to create a unit test using Moq which test Microsoft.AspNetCore.Identity user manager. I know that Moq is good for mocking interfaces, but UserManager does not have interface.

Here is my code:

Mock<UserManager<User>> userManagerMock = new Mock<UserManager<User>>();
// rest of my code ...

here is the error:

Castle.DynamicProxy.InvalidProxyConstructorArgumentsException : Can not instantiate proxy of class: Microsoft.AspNetCore.Identity.UserManager`1[[WebAPI.Core.Model.User, Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]. Could not find a parameterless constructor.


Solution

  • You can mock classes with Moq. You just need to create a new Mock with valid constructor parameters. In your case:

    var userManagerMock = new Mock<UserManager<User>>(Mock.Of<IUserStore<User>>(), null, null, null, null, null, null, null, null);
    

    When creating new mock for class, Moq uses one of the constructors of the class, in the UserManager class, there is a single constructor with 9 parameters:

    UserManager<TUser>(IUserStore<TUser>, IOptions<IdentityOptions>, IPasswordHasher<TUser>, IEnumerable<IUserValidator<TUser>>, IEnumerable<IPasswordValidator<TUser>>, ILookupNormalizer, IdentityErrorDescriber, IServiceProvider, ILogger<UserManager<TUser>>)
    

    The only parameter that is mandatory is the first one, all the others you can pass null value.

    Now you can setup any virtual method or property.

    Full example:

    [TestMethod]
    public void MockUserManager()
    {
        // Arrange
        var userManagerMock = new Mock<UserManager<User>>(Mock.Of<IUserStore<User>>(), null, null, null, null, null, null, null, null);
        userManagerMock.Setup(x => x.CheckPasswordAsync(It.IsAny<User>(), It.IsAny<string>())).ReturnsAsync(true);
    
        // Act
        var res = userManagerMock.Object.CheckPasswordAsync(new User(), "123456").Result;
    
        // Assert
        Assert.IsTrue(res);
    }
    
    public class User
    {
    }