c# - 如何模拟 UserManager<IdentityUser>

标签 c# asp.net-core asp.net-identity moq xunit

我正在尝试研究如何将单元测试添加到我的项目中。我认为最好从一个空白项目开始,然后从头开始解决,而不是将其添加到我的主项目中。一旦我理解了这个过程,我想我可以开始重构我的项目以添加测试。

网络应用

所以我创建了一个 Web 应用程序并向其添加了默认用户身份。

这给了我一个看起来像这样的开始

public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));
        services.AddDefaultIdentity<IdentityUser>()
            .AddEntityFrameworkStores<ApplicationDbContext>();

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    }

然后我创建了一个简单的 Controller 并在构造函数中传递了用户管理器。

[Route("api/[controller]")]
[ApiController]
public class SweetController : ControllerBase
{
    private readonly UserManager<IdentityUser> _userManager;

    public SweetController(UserManager<IdentityUser> userManager)
    {
        _userManager = userManager;
    }
    public async Task<int> NumberOfGummyBearsForUser(string userId)
    {
        var user = await _userManager.FindByIdAsync(userId);
        var userHasASweetTooth = await _userManager.IsInRoleAsync(user, "SweetTooth");
        if (userHasASweetTooth)
        {
            return 100;
        }
        else
        {
            return 1;
        }
    }
}

单元测试

我一直在尝试做的第一件事是模拟这个用户管理器,但它不起作用。

public void Test1()
    {
        // Arrange
        var mockUser = new Mock<UserManager<IdentityUser>>();
        var userManager = new UserManager(mockRepo.Object);  <-- error here see image below

        var controller = new SweetController(userManager.Object);

        // Act
        var result = await controller.NumberOfGummyBearsForUser("123");

        // Assert
        Assert.Equal(100, result);
    }

错误看起来像这样

enter image description here

我想我需要传递更多信息来创建这个 usermanager 对象,但我不确定我找到的所有教程都使用 ApplicationUser 而不是 IdentityUser,所以我不知道如何模拟这个对象。

最佳答案

你就是这样

// Arrange
var mockUser = new Mock<UserManager<IdentityUser>>();

var controller = new SweetController(mockUser.Object);

你不需要

var userManager = new UserManager(mockRepo.Object);  <-- error here see image below

完全没有。 mockUser已经是 mock UserManager<T> ,你通过 mock.Object 放置一个模拟实例.

当你模拟一个对象时,你不必用它的所有依赖项来实例化它(那将是集成测试),这就是模拟的重点(以及使方法返回所需的值并进行行为测试以确保您的测试代码调用了具有模拟对象的特定参数的特定方法。

当然,上面的代码本身是行不通的,因为您没有为 FindByIdAsync 设置任何测试条件/返回值。和 IsInRoleAsync .您必须使用

设置这些
mockUser.Setup( userManager => userManager.FindByIdAsync(It.IsAny<string>()))
    .ReturnsAsync(new IdentityUser { ... });
mockUser.Setup( userManager => userManager.IsInRoleAsync(It.IsAny<IdentityUser>(), "SweetTooth"))
    .ReturnsAsync(true);

然后,无论何时调用模拟,它都会返回您预定义的用户和预定义的结果。

关于c# - 如何模拟 UserManager<IdentityUser>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55412776/

相关文章:

c# - 将 FlowDocument 添加到主窗口

azure - 从 .NET Core 1.1.1 升级到 .NET Core 1.1.2 后,Azure 上的 ASP.NET Core 网站无法启动并出现 502.5 错误

docker - Docker : Drive has not been shared

header - asp.net core 删除 X-Powered-By 不能在中间件中完成

Asp.Net Identity - 登录后更新声明

javascript - Apache Cordova 在 MVC5 中连接到 Asp.net Web 应用程序

c# - 如何将任意 DataTable 保存到新的 SQL 表

c# - 如何使用 C# Windows 窗体读取 Excel 中的多个单元格

c# - 带有以 c# 中的关键字 word 命名的参数的 API

c# - asp.net core 2.0身份 Entity Framework 用户未保存