测试 usermanager 创建一个用户,但密码哈希 属性 为空

Testing usermanager creates a user but password hash property is null

我正在与 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'returns这个:

    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 传递给处理新用户创建的方法,其中 '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 IS populated.

好的,但是生成一些密码的内部代码对 (x,y) => {..} 参数没有任何影响。

查看此代码(复制自 this 很好的答案):

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 方法内部发生了什么,输出将仅取决于模拟函数的调用参数值。