gpt4 book ai didi

c# - Asp .Net Core 单元测试模拟 UserManager.CreateAsync 并返回身份结果

转载 作者:行者123 更新时间:2023-12-04 15:37:01 27 4
gpt4 key购买 nike

致力于 .Net Core 项目并创建了以下服务以跨页面共享通用方法。

namespace MyApp.Tests.Services
{
public class UserServiceTest
{
[Fact]
public async Task CreateUser_ShouldCreateUser()
{
var user = new UserResponse
{
Id = "111",
Email = "john@email.com",
FirstName = "John",
LastName = "Doe",
CompanyName = "SomeCompany",
PhoneNumber = "9123456789"
};

var appUser = new ApplicationUser
{
UserName = user.Email,
Email = user.Email,
FirstName = user.FirstName,
LastName = user.LastName,
CompanyName = user.CompanyName,
PhoneNumber = user.PhoneNumber
};

var logger = Mock.Of<ILogger<UserService>>();
var mockUserStore = new Mock<IUserStore<ApplicationUser>>();
mockUserStore
.Setup(x => x.CreateAsync(appUser, CancellationToken.None))
.ReturnsAsync(IdentityResult.Success).Verifiable();

// Tried this one as well but still getting null instead of IdentityResult
// mockUserStore
// .Setup(x => x.CreateAsync(appUser, CancellationToken.None))
// .ReturnsAsync(new IdentityResultMock(true));

var userManager = new UserManager<ApplicationUser>(mockUserStore.Object, null, null, null, null, null, null, null, null);
var _userService = new UserService(userManager, logger);

var result = await _userService.CreateUserInApp(user);

Assert.True(result.Succeeded);
}
}

public class IdentityResultMock : IdentityResult
{
public IdentityResultMock(bool succeeded) {
base.Succeeded = succeeded;
}
}
}

还为此服务编写了单元测试用例,如下所示以测试 UserService

namespace MyApp.Tests.Services
{
public class UserServiceTest
{
[Fact]
public async Task CreateUser_ShouldCreateUser()
{
var user = new UserResponse
{
Id = "111",
Email = "john@email.com",
FirstName = "John",
LastName = "Doe",
CompanyName = "SomeCompany",
PhoneNumber = "9123456789"
};

var appUser = new ApplicationUser
{
UserName = user.Email,
Email = user.Email,
FirstName = user.FirstName,
LastName = user.LastName,
CompanyName = user.CompanyName,
PhoneNumber = user.PhoneNumber
};

var logger = Mock.Of<ILogger<UserService>>();
var mockUserStore = new Mock<IUserStore<ApplicationUser>>();
mockUserStore
.Setup(x => x.CreateAsync(appUser, CancellationToken.None))
.ReturnsAsync(IdentityResult.Success).Verifiable(); ;

var userManager = new UserManager<ApplicationUser>(mockUserStore.Object, null, null, null, null, null, null, null, null);
var _userService = new UserService(userManager, logger);

var result = await _userService.CreateUserInApp(user);

Assert.True(result.Succeeded);
}
}
}

的用户服务中运行测试时
var createResult = await _userManager.CreateAsync(appUser);

createResult 由于此测试用例失败并出现空引用异常,我得到空值。如果我可以从模拟 CreateAsync 设置返回 IdentityResult,那么它将通过但不确定我在做什么错。也无法创建 IdentityResult 的对象,因为“成功” protected 并且无法显式分配值。请帮忙。谢谢 :)

最佳答案

我们需要看看构造函数内部发生了什么:

var userManager = new UserManager<ApplicationUser>(mockUserStore.Object, null, null, null, null, null, null, null, null);

但实际上并非如此。如果您在这里测试 UserService,那么您应该模拟的是 UserManager 而不是它的内部依赖项 IUserStore

这是为什么呢?因为 UserManager 的内部结构可能会发生变化,所以您必须同时更改 UserManager 测试和 UserService 测试。

像创建 IUserStore 一样模拟 UserManager 的创建,您会发现它是 UserStore 中的其他依赖项或完全超出单元范围的某个地方测试。

编辑 1

我想我已经解决了你的问题:

mockUserStore
.Setup(x => x.CreateAsync(appUser, CancellationToken.None))
.ReturnsAsync(IdentityResult.Success).Verifiable();

调用

var result = await _userService.CreateUserInApp(user);

User 对象和 appUser 对象不一样,所以 mocking 框架没有返回预期的值。

为确保这是问题所在,请尝试模拟

mockUserStore
.Setup(x => x.CreateAsync(It.IsAny<ApplicationUser>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(IdentityResult.Success).Verifiable();

关于c# - Asp .Net Core 单元测试模拟 UserManager.CreateAsync 并返回身份结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59387380/

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