gpt4 book ai didi

c# - 如何使用 NUnit 在 .NET Core 中模拟 UserManager?

转载 作者:行者123 更新时间:2023-11-30 15:16:00 26 4
gpt4 key购买 nike

我想使用 Razor Pages 对我在 .NET Core 中制作的应用程序进行单元测试。我需要模拟我的 dbContext 和我的 UserManager - 但是,我似乎一直在返回 null 作为结果。

假用户管理器

public class FakeUserManager : UserManager<ApplicationUser>
{
public FakeUserManager()
: base(new Mock<IUserStore<ApplicationUser>>().Object,
new Mock<IOptions<IdentityOptions>>().Object,
new Mock<IPasswordHasher<ApplicationUser>>().Object,
new IUserValidator<ApplicationUser>[0],
new IPasswordValidator<ApplicationUser>[0],
new Mock<ILookupNormalizer>().Object,
new Mock<IdentityErrorDescriber>().Object,
new Mock<IServiceProvider>().Object,
new Mock<ILogger<UserManager<ApplicationUser>>>().Object)
{ }
}

我的测试类

 [TestFixture]
public class UserTest
{
private ApplicationDbContext _dbContext { get; set; }
public void TestSetUp()
{
DbContextOptionsBuilder<ApplicationDbContext> optionsbuilder = new DbContextOptionsBuilder<ApplicationDbContext>();
optionsbuilder.UseInMemoryDatabase(databaseName: "TestDB");
_dbContext = new ApplicationDbContext(optionsbuilder.Options);
_dbContext.Users.Add(new ApplicationUser
{
Id = "1",
FirstName = "Test",
LastName = "Alpha",
CreatedAt = DateTime.Now,
UpdatedAt = DateTime.Now,
});
_dbContext.SaveChanges();
}

[Test]
public void MyTest()
{
Mock<FakeUserManager> fakeUserManager = new Mock<FakeUserManager>();
var result = fakeUserManager.Object.FindByIdAsync("1");

// I know this Assert always returns success, but I'd like var result to return my ApplicationUser found by the FakeUserManager
Assert.AreEqual("test", "test");
}
}

在将此问题标记为重复之前,是的 - 我会查看其他帖子,但它们不满足我的回答。

当我运行这个测试时,var result 返回 null,我不明白为什么。

编辑###

    [Test]
public async void MyTest()
{
var mockStore = Mock.Of<IUserStore<ApplicationUser>>();
var mockUserManager = new Mock<UserManager<ApplicationUser>>(mockStore, null, null, null, null, null, null, null, null);

var user = new ApplicationUser
{
Id = "1",
FirstName = "Test",
LastName = "Test"
};

mockUserManager
.Setup(x => x.CreateAsync(It.IsAny<ApplicationUser>(), It.IsAny<string>()))
.ReturnsAsync(IdentityResult.Success);

await mockUserManager.Object.CreateAsync(user);

var result = mockUserManager.Object.FindByIdAsync("UserA");

Assert.AreEqual("test", "test");


}

最佳答案

您不应该测试 UserManager 是否可以从数据库中检索数据(这是超出您范围的框架的内部问题)。相反,您应该像这样为 UserManager 模拟 FindByIdAsync 的功能:

var UserStoreMock = Mock.Of<IUserStore<AppUser>>();
var userMgr = new Mock<UserManager<AppUser>>(UserStoreMock, null, null, null, null, null, null, null, null);
var user = new AppUser() { Id = "f00", UserName = "f00", Email = "f00@example.com" };
var tcs = new TaskCompletionSource<AppUser>();
tcs.SetResult(user);
userMgr.Setup(x => x.FindByIdAsync("f00")).Returns(tcs.Task);

对于您的身份设置,以确保具有适当权限的经过身份验证的用户正在调用电话:

Mock<ClaimsPrincipal> ClaimsPrincipalMock = new Mock<ClaimsPrincipal>();
ClaimsPrincipalMock.Setup(x => x.IsInRole("Admin")).Returns(true);
ClaimsPrincipalMock.Name = "SomeAdmin";
ClaimsPrincipalMock.SetupGet(x => x.Identity.Name).Returns(ClaimsPrincipalMock.Name);

然后为您的帐户 Controller 设置上下文,将您的 UserManager 作为 DI 参数之一传递:

AccountController SUT = new AccountController(userMgr);
var context = new ControllerContext();
context.HttpContext = new DefaultHttpContext();
context.HttpContext.User = ClaimsPrincipalMock.Object;
SUT.ControllerContext = context;

最后,在您的 Controller 中,匹配代码将类似于:

[HttpGet("User")]
public async Task<IActionResult> GetUser(string id)
{
var user = await _userManager.FindByIdAsync(id);
bool isAdmin= User.IsInRole("Admin");

if (user == default(AppUser) || (User.Identity.Name != user.UserName && isAdmin == false))
{
return NotFound();
}

return Ok(user);
}

关于c# - 如何使用 NUnit 在 .NET Core 中模拟 UserManager?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50889418/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com