如何模拟UserManager< IdentityUser> [英] How to mock UserManager<IdentityUser>

查看:251
本文介绍了如何模拟UserManager< IdentityUser>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试找出如何向我的项目中添加单元测试.我认为最好从一个空白项目开始,并从头开始进行设计,而不是将其添加到我的主项目中.一旦了解了流程,我便可以开始重构我的项目以添加测试.

I am trying to work out how to add unit testing to my project. I thought it was best to start with a blank project and work it out from the start rather than adding it to my main project. Once I understand the process i figure i can start refactoring my project for adding testing.

因此,我创建了一个Web应用程序,并向其中添加了默认用户身份.

So i created a web application and added default user identity to it.

这给了我一个像这样的启动

This gave me a start up looking like this

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);
    }

然后我创建了一个简单的控制器,并在构造函数中传递了usermanager.

Then i created a simple controller and passed the usermanager in the constructor.

[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;
        }
    }
}

单元测试

我一直想做的第一件事是模拟该用户管理器,但它不起作用.

Unit Test

The first thing i have been trying to do is mock this user manager but its not working.

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);
    }

错误看起来像这样

我认为我需要通过更多的操作来创建该usermanager对象,但是我不确定我找到的所有教程都使用ApplicationUser而不是IdentityUser,所以我对如何模拟该对象感到困惑.

I think i need to pass more to create this usermanager object but i am not sure what all the tutorials i have found use ApplicationUser and not IdentityUser so i am at a loss as to how i can mock this object.

推荐答案

您只需

// 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已经是模拟的UserManager<T>,您可以通过mock.Object放置模拟的实例.

at all. mockUser is already the mocked UserManager<T>, which you place a mocked instance via mock.Object.

当模拟对象时,您不必使用其所有依赖关系实例化它(这将是集成测试),这就是模拟的重点(连同使方法返回所需的值并进行行为测试以确保您测试的代码调用了带有模拟对象特定参数的特定方法.

When you mock an object you don't have to instantiate it with all of its dependencies (that would be integration test), that's the point of mocking (along with making methods return a desired value and do behavior tests to make sure your tested code has called a specific method with specific parameter of the mocked object).

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

Of course per se the above code won't work, since you didn't setup any test conditions/returns for FindByIdAsync and IsInRoleAsync. You have to setup these with

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

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

Then whenever the mock is called it returns your predefined user and a predefined result.

这篇关于如何模拟UserManager&lt; IdentityUser&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆