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.
CodePudding user response:
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
{
}