c# - 测试用户管理器创建用户但密码哈希属性为空
问题描述
我正在使用 Microsoft.AspNetCore.Identity.UserManager 并试图模拟新用户的创建。事实上,它确实使用用户名、电子邮件等创建了一个新用户,但密码哈希属性仍然为空。
这就是我如何通过一些额外的设置来设置模拟用户管理器:
var store = new Mock<IUserPasswordStore<User>>();
var validator = new UserValidator<User>();
var passValidator = new PasswordValidator<User>();
var mgr = new Mock<UserManager<User>>(store.Object, null, null, null, null, null, null, null, null);
mgr.Object.UserValidators.Add(validator);
mgr.Object.PasswordValidators.Add(passValidator);
mgr.Object.PasswordHasher = new PasswordHasher<User>();
mgr.Object.Options = AuthenticationRules.DefaultAuthenticationRules();
List<User> users= new List<User>();
mgr.Setup(x => x.DeleteAsync(It.IsAny<User>())).ReturnsAsync(IdentityResult.Success);
mgr.Setup(x => x.CreateAsync(It.IsAny<User>(), It.IsAny<string>())).ReturnsAsync(IdentityResult.Success).Callback<User, string>((x, y) => users.Add(x));
mgr.Setup(x => x.UpdateAsync(It.IsAny<User>())).ReturnsAsync(IdentityResult.Success);
'DefaultAuthenticationRules' 返回:
public static IdentityOptions DefaultAuthenticationRules(IdentityOptions identityOptions = null)
{
if(identityOptions == null)
identityOptions = new IdentityOptions();
identityOptions.User.RequireUniqueEmail = true;
identityOptions.Password.RequireNonAlphanumeric = false;
identityOptions.Password.RequiredUniqueChars = 0;
return identityOptions;
}
然后,我将 mgr.Object 传递给处理创建新用户的方法,其中“对象”为 _userManager
var creationResult = await _userManager.CreateAsync(_user, _registrationModel.Password);
if (!creationResult.Succeeded)
return false;
return true;
_registrationModel.Password 已填充。
所以现在当设置在回调中添加一个新用户到用户列表时,用户会在没有密码哈希的情况下填充。我不确定我在这里缺少什么。我在 mgr.Setup 中遗漏了一些东西?
提前致谢
解决方案
您的回调函数Callback<User, string>((x, y) => users.Add(x));
将在测试完成后执行,它将接受您传递给模拟方法的相同参数值作为参数,在您的情况下,密码可能是空字符串或 null。
_registrationModel.Password 已填充。
好的,但是生成一些密码的内部代码对参数没有任何影响(x,y) => {..}
。
请参阅此代码(从this great answer复制):
public interface IFoo
{
int Bar(bool b);
}
var mock = new Mock<IFoo>();
mock.Setup(mc => mc.Bar(It.IsAny<bool>()))
.Callback<bool>(b => Console.WriteLine("Bar called with: " + b))
.Returns(99999);
var ret1 = mock.Object.Bar(true);
Console.WriteLine("Result ret1: " + ret1);
var ret2 = mock.Object.Bar(false);
Console.WriteLine("Result ret2: " + ret2);
//OUTPUT:
//Result ret1: true.
//Result ret1: false.
在示例中,无论方法内部发生什么Bar
,输出都将仅取决于模拟函数的调用参数值。
推荐阅读
- docusignapi - DocuSign 锚选项卡不可修改
- python - Django queryset iterator() 没有按预期工作
- amazon-web-services - 亚马逊实例上的磁盘缓存/性能问题
- javascript - JavaScript:读取一个项目 AWS dynamodb
- c# - Service Fabric 无状态服务的多个分区、多个节点的设置
- java - JUnit + Powermock - 新日期() - NullPointerException
- c# - 如何在 URL 路径中正确编码 Web API 参数?
- java - 单击组合框选项时不显示切换大小写字符串
- javascript - 从根目录下没有 package.json 的 git 安装 npm 模块
- .net - 如何在同一地址上托管 Web API 和 MVC 应用程序