提问人:coolhand 提问时间:12/27/2017 最后编辑:Nkosicoolhand 更新时间:6/26/2019 访问量:2014
在 ASP.NET Core 中对自定义密码验证程序进行单元测试
Unit Testing Custom Password Validators in ASP.NET Core
问:
我有一个覆盖密码验证器的 CustomPasswordValidator.cs 文件
public class CustomPasswordValidator : PasswordValidator<AppUser>
{ //override the PasswordValidator functionality with the custom definitions
public override async Task<IdentityResult> ValidateAsync(UserManager<AppUser> manager, AppUser user, string password)
{
IdentityResult result = await base.ValidateAsync(manager, user, password);
List<IdentityError> errors = result.Succeeded ? new List<IdentityError>() : 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 的新手。我正在尝试创建一个单元测试,以确保产生正确数量的错误(显示工作代码,以及在注释中产生错误的代码):
//test the ability to validate new passwords with Infrastructure/CustomPasswordValidator.cs
[Fact]
public async void Validate_Password()
{
//Arrange
<Mock><UserManager<AppUser>> userManager = new <Mock><UserManager<AppUser>>(); //caused null exception, use GetMockUserManager() instead
<Mock><CustomPasswordValidator> customVal = new <Mock><CustomPasswordValidator>(); //caused null result object use customVal = new <CustomPasswordValidator>() instead
<AppUser> user = new <AppUser>
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<IdentityError> errors = result.Succeeded ? new List<IdentityError>() : result.Errors.ToList();
Assert.Equal(errors.Count, 2);
}
//create a mock UserManager class
private Mock<UserManager<AppUser>> GetMockUserManager()
{
var userStoreMock = new Mock<IUserStore<AppUser>>();
return new Mock<UserManager<AppUser>>(
userStoreMock.Object, null, null, null, null, null, null, null, null);
}
该错误发生在 IdentityResult 行上,指示我无法将 Mock 转换为 UserManager,也无法将 Mock 转换为 AppUser 类。
编辑:更改为包含 GetMockUserManager() 在核心中模拟 UserManagerClass 所需的 ASP.NET (模拟新Microsoft实体框架标识 UserManager 和 RoleManager)
答:
4赞
Nkosi
12/27/2017
#1
使用 Moq,您需要调用 mock 来获取 mock 对象。您还应该使测试异步并等待所测试的方法。.Object
您还模拟了被测主题,在这种情况下,这会导致被测方法在调用时返回 null,因为它没有正确设置。在这一点上,您基本上是在测试模拟框架。
创建被测主体的实际实例并执行测试,模拟被测主体的显式依赖关系以获得所需的行为。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
}
阅读最小起订量快速入门,更熟悉如何使用最小起订量。
上一个:在 Razor 中递增索引计数器
评论