我已经模拟了userManager并使用返回值设置了所需的功能。
但是,即使我设置的返回值不同,每次尝试运行单元测试时,我仍然会得到错误/失败的返回值。
[TestCase]
public async Task Verify_UserInRole_False()
{
var userRole = "Supervisor";
var email = "test@test.com";
var mockUserStore = new Mock<IUserStore<IdentityUser>>();
var mockUserRoleStore = mockUserStore.As<IUserRoleStore<IdentityUser>>();
var mockedUserManager = new Mock<UserManager<IdentityUser>>(new Mock<IUserStore<IdentityUser>>(mockUserRoleStore).Object,
new Mock<IOptions<IdentityOptions>>().Object,
new Mock<IPasswordHasher<IdentityUser>>().Object,
new IUserValidator<IdentityUser>[0],
new IPasswordValidator<IdentityUser>[0],
new Mock<ILookupNormalizer>().Object,
new Mock<IdentityErrorDescriber>().Object,
new Mock<IServiceProvider>().Object,
new Mock<ILogger<UserManager<IdentityUser>>>().Object);
mockedUserManager.Setup(x => x.FindByEmailAsync(email))
.ReturnsAsync(It.Is<IdentityUser>(u => u.UserName == email));
mockUserRoleStore.Setup(x => x.IsInRoleAsync(It.Is<IdentityUser>(u => u.UserName == email), userRole, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
AdminController adminController = new AdminController(hostingEnvironment, signInManager, logger, roleManager, mockedUserManager.Object);
var actionResult = await adminController.CheckIfUserIsInRole(email, userRole);
Assert.IsTrue(actionResult);
}
要测试的方法:
public async Task<bool> CheckIfUserIsInRole(string email, string role)
{
return await _userManager.IsInRoleAsync(await _userManager.FindByEmailAsync(email), role);
}
userManager的各种方法(如 AddToRole())仍然存在相同的情况;等
据我了解: 当我嘲笑 IsInRoleAsync()时, 按下 CheckIfUserIsInRole(...)方法后, IsInRoleAsync()应该由模拟对象替换,并应返回我们配置的模拟对象返回的任何内容。
我在做什么错了?
谢谢:)
答案 0 :(得分:1)
问题出在模拟程序的设置上。如果您使用特定的对象或值,moq
将使用IEquatable.Equals
比较实例。您具有以下设置:
mockedUserManager.Setup(x => x.FindByEmailAsync(email))
.ReturnsAsync(new IdentityUser { UserName = email });
mockUserRoleStore.Setup(x => x.IsInRoleAsync(new IdentityUser() { UserName = email }, userRole, ct))
.ReturnsAsync(true);
由于您每次创建新实例时,您的设置都不会真正匹配。考虑将第二种设置更改为:
mockUserRoleStore.Setup(x => x.IsInRoleAsync(It.IsAny<IdentityUser>(), userRole, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
或更具体地说
mockUserRoleStore.Setup(x => x.IsInRoleAsync(It.Is<IdentityUser>(u => u.UserName == email), userRole, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
更新
我注意到了另一个问题,因为您不是使用模拟的mockedUserManager
而是使用新的模拟实例来初始化mockUserRoleStore
:
var mockUserRoleStore = mockUserStore.As<IUserRoleStore<IdentityUser>>();
var mockedUserManager = new Mock<UserManager<IdentityUser>>(mockUserRoleStore.Object,
new Mock<IOptions<IdentityOptions>>().Object,
new Mock<IPasswordHasher<IdentityUser>>().Object,
new IUserValidator<IdentityUser>[0],
new IPasswordValidator<IdentityUser>[0],
new Mock<ILookupNormalizer>().Object,
new Mock<IdentityErrorDescriber>().Object,
new Mock<IServiceProvider>().Object,
new Mock<ILogger<UserManager<IdentityUser>>>().Object);