ASP.NET核心中的unit testing自定义密码validation器

我有一个CustomPasswordValidator.cs文件覆盖PasswordValidator

public class CustomPasswordValidator : PasswordValidator { //override the PasswordValidator functionality with the custom definitions public override async Task ValidateAsync(UserManager manager, AppUser user, string password) { IdentityResult result = await base.ValidateAsync(manager, user, password); List errors = result.Succeeded ? new List() : result.Errors.ToList(); //check that the username is not in the password if (password.ToLower().Contains(user.UserName.ToLower())) { errors.Add(new IdentityError { Code = "PasswordContainsUserName", Description = "Password cannot contain username" }); } //check that the password doesn't contain '12345' if (password.Contains("12345")) { errors.Add(new IdentityError { Code = "PasswordContainsSequence", Description = "Password cannot contain numeric sequence" }); } //return Task.FromResult(errors.Count == 0 ? IdentityResult.Success : IdentityResult.Failed(errors.ToArray())); return errors.Count == 0 ? IdentityResult.Success : IdentityResult.Failed(errors.ToArray()); } } 

我是使用Moq和xUnit的新手。 我正在尝试创建一个unit testing,以确保产生正确数量的错误(显示工作代码,代码在注释中产生错误):

 //test the ability to validate new passwords with Infrastructure/CustomPasswordValidator.cs [Fact] public async void Validate_Password() { //Arrange <UserManager> userManager = new <UserManager>(); //caused null exception, use GetMockUserManager() instead  customVal = new (); //caused null result object use customVal = new () instead  user = new  user.Name = "user" //set the test password to get flagged by the custom validator string testPwd = "Thi$user12345"; //Act //try to validate the user password IdentityResult result = await customVal.ValidateAsync(userManager, user, testPwd); //Assert //demonstrate that there are two errors present List errors = result.Succeeded ? new List() : result.Errors.ToList(); Assert.Equal(errors.Count, 2); } //create a mock UserManager class private Mock<UserManager> GetMockUserManager() { var userStoreMock = new Mock<IUserStore>(); return new Mock<UserManager>( userStoreMock.Object, null, null, null, null, null, null, null, null); } 

IdentityResult行上发生错误,表示我无法将Mock转换为UserManager,并且无法将Mock转换为AppUser类。

编辑:更改为包含模拟ASP.NET核心中的UserManagerClass所需的GetMockUserManager()(模拟新的Microsoftentity framework标识UserManager和RoleManager )

使用Moq,您需要在模拟上调用.Object来获取模拟对象。 您还应该使测试异步并等待测试中的方法。

您还在模拟测试中的主题,在这种情况下,导致被测方法在调用时返回null,因为它不会被正确设置。 您基本上是在测试模拟框架。

在测试CustomPasswordValidator下创建主题的实际实例并执行测试, CustomPasswordValidator测试对象的显式依赖关系以获得所需的行为。

 public async Task Validate_Password() { //Arrange var userManagerMock = new GetMockUserManager(); var subjetUnderTest = new CustomPasswordValidator(); var user = new AppUser() { Name = "user" }; //set the test password to get flagged by the custom validator var password = "Thi$user12345"; //Act IdentityResult result = await subjetUnderTest.ValidateAsync(userManagerMock.Object, user, password); //...code removed for brevity } 

阅读Moq快速入门 ,以便更熟悉如何使用moq。