如何模拟Asp.net身份UserManager';s CreateAsync方法

本文关键字:UserManager 方法 CreateAsync 身份 net 何模拟 模拟 Asp | 更新日期: 2024-07-10 19:25:33

我正试图模拟UserStore的CreateAsync方法,使其具有内存中的用户存储。

public void Can_Create_User()
{
    //Arrange
    var dummyUser = new ApplicationUser() { UserName = "PinkWarrior", Email = "PinkWarrior@PinkWarrior.com" };
    var mockStore = new Mock<IUserStore<ApplicationUser>>();
    var userManager = new UserManager<ApplicationUser>(mockStore.Object);
    mockStore.Setup(x => x.CreateAsync(dummyUser))
                .Returns(Task.FromResult(IdentityResult.Success));

    //Act
    Task<IdentityResult> tt = (Task<IdentityResult>)mockStore.Object.CreateAsync(dummyUser);
    var user = userManager.FindByName("PinkWarrior");
    //Assert
    Assert.AreEqual("PinkWarrior", user.UserName);
}

上面的user总是空的,因为我从来没有插入它。所以我的问题是我如何制作userManager,它不是从我的模拟商店向用户返回的模拟

这个答案有点类似,但并不能回答我的问题。

任何帮助都非常感谢

如何模拟Asp.net身份UserManager';s CreateAsync方法

您需要模拟对FindByNameAsync的调用,因为这就是UserManager将调用的:

public void Can_Create_User()
{
    //Arrange
    var dummyUser = new ApplicationUser() { UserName = "PinkWarrior", Email = "PinkWarrior@PinkWarrior.com" };
    var mockStore = new Mock<IUserStore<ApplicationUser>>();
    var userManager = new UserManager<ApplicationUser>(mockStore.Object);
    mockStore.Setup(x => x.CreateAsync(dummyUser))
                .Returns(Task.FromResult(IdentityResult.Success));
    mockStore.Setup(x => x.FindByNameAsync(dummyUser.UserName))
                .Returns(Task.FromResult(dummyUser));

    //Act
    Task<IdentityResult> tt = (Task<IdentityResult>)mockStore.Object.CreateAsync(dummyUser);
    var user = userManager.FindByName("PinkWarrior");
    //Assert
    Assert.AreEqual("PinkWarrior", user.UserName);
}

但是,我相信通过这样的测试,您测试的是Microsoft.AspNet.Identity.UserManager,而不是您的代码。您正在证明的是UserManager以某种方式调用了您的mockStore。

Microsoft.AspNet.Identity的源代码包含这些类型的测试。

Identity git repo 中的测试中检查MockHelper.cs

识别GitHub回购链接或已关闭的问题以嘲笑

你应该在那里找到关于模拟的灵感,例如

  public static UserManager<TUser> TestUserManager<TUser>(IUserStore<TUser> store = null) where TUser : class
    {
        store = store ?? new Mock<IUserStore<TUser>>().Object;
        var options = new Mock<IOptions<IdentityOptions>>();
        var idOptions = new IdentityOptions();
        idOptions.Lockout.AllowedForNewUsers = false;
        options.Setup(o => o.Value).Returns(idOptions);
        var userValidators = new List<IUserValidator<TUser>>();
        var validator = new Mock<IUserValidator<TUser>>();
        userValidators.Add(validator.Object);
        var pwdValidators = new List<PasswordValidator<TUser>>();
        pwdValidators.Add(new PasswordValidator<TUser>());
        var userManager = new UserManager<TUser>(store, options.Object, new PasswordHasher<TUser>(),
            userValidators, pwdValidators, new UpperInvariantLookupNormalizer(),
            new IdentityErrorDescriber(), null,
            new Mock<ILogger<UserManager<TUser>>>().Object,
            null);
        validator.Setup(v => v.ValidateAsync(userManager, It.IsAny<TUser>()))
            .Returns(Task.FromResult(IdentityResult.Success)).Verifiable();
        return userManager;
    }

我用这种方法:

       private UserController BuildCoontrollerWithDatabase()
    {
        DbContextOptionsBuilder dbContextOptionsBuilder = new DbContextOptionsBuilder();
        dbContextOptionsBuilder.UseInMemoryDatabase();
        ApplicationDbContext applicationDbContext = new ApplicationDbContext( dbContextOptionsBuilder.Options);
        var userStore = new UserStore<ApplicationUser>(applicationDbContext);
        UserManager<ApplicationUser>  userManager = TestUserManager<ApplicationUser>(userStore);
        return new UserController(userManager);

    }

您的模拟用户存储没有正确准备。由于它是一个mock,您不应该期望mockStore.Object.CreateAsync会做任何事情,也就是说,它不会在任何地方添加任何内容。

您需要准备相应的"读取"操作,因为用户管理器很可能会调用它。(在mock上设置FindByNameAsync方法以返回所需的标识)。

在任何情况下,您试图做的都是毫无意义的,因为您试图测试一个框架类UserManager。

您实际需要的可能是模拟用户管理器本身,并在控制器中或在任何使用该用户管理器的地方使用该模拟。

这适用于我的

    public void Can_Create_User()
    {
        //Arrange
        var dummyUser = new ApplicationUser() { UserName = "PinkWarrior", Email = "PinkWarrior@PinkWarrior.com" };
        var mockStore = new Mock<IUserStore<ApplicationUser>>();
        var userManager = new UserManager<ApplicationUser>(mockStore.Object, null, null, null, null, null, null, null, null);
        mockStore.Setup(s => s.CreateAsync(It.IsAny<ApplicationUser>(), CancellationToken.None))
            .Returns(Task.FromResult(IdentityResult.Success));
        mockStore.Setup(s => s.FindByNameAsync(It.IsAny<string>(), CancellationToken.None))
            .Returns(Task.FromResult(dummyUser)).Verifiable();
        //Act
        Task<IdentityResult> tt = (Task<IdentityResult>)mockStore.Object.CreateAsync(dummyUser,CancellationToken.None);
        var user = userManager.FindByNameAsync("PinkWarrior");
        user.Wait();
        //Assert
        Assert.True("PinkWarrior" == user.Result.UserName);
    }