首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何模拟UserManager<IdentityUser>

如何模拟UserManager<IdentityUser>
EN

Stack Overflow用户
提问于 2019-03-29 07:52:40
回答 2查看 7.1K关注 0票数 9

我正在尝试如何将单元测试添加到我的项目中。我认为最好从一个空白项目开始,从一开始就完成它,而不是把它添加到我的主要项目中。一旦我理解了这个过程,我就可以开始重构我的项目以添加测试。

web应用程序

因此,我创建了一个web应用程序,并在其中添加了默认的用户标识。

这让我开始看上去像这样

代码语言:javascript
复制
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);
    }

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

代码语言:javascript
复制
[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;
        }
    }
}

单元测试

我一直试图做的第一件事就是嘲笑这个用户管理器,但它不起作用。

代码语言:javascript
复制
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);
    }

错误如下所示

我想我需要传递更多来创建这个用户管理器对象,但是我不知道我找到的所有教程都使用了ApplicationUser而不是IdentityUser,所以我对如何模拟这个对象感到困惑。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-03-29 08:15:07

你就这么做

代码语言:javascript
复制
// Arrange
var mockUser = new Mock<UserManager<IdentityUser>>();

var controller = new SweetController(mockUser.Object);

你不需要

代码语言:javascript
复制
var userManager = new UserManager(mockRepo.Object);  <-- error here see image below

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

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

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

代码语言:javascript
复制
mockUser.Setup( userManager => userManager.FindByIdAsync(It.IsAny<string>()))
    .ReturnsAsync(new IdentityUser { ... });
mockUser.Setup( userManager => userManager.IsInRoleAsync(It.IsAny<IdentityUser>(), "SweetTooth"))
    .ReturnsAsync(true);

然后,每当调用模拟时,它都会返回预定义用户和预定义结果。

票数 6
EN

Stack Overflow用户

发布于 2019-03-29 09:41:22

在曾的帮助下我完成了这个任务。一个完全工作的版本是

控制器

代码语言:javascript
复制
   private readonly UserManager<IdentityUser> _userManager;

    public SweetController(UserManager<IdentityUser> userManager)
    {
        _userManager = userManager;
    }

    public async Task<IdentityUser> GetUser(string userId)
    {
        var user = await _userManager.FindByIdAsync(userId);
        return user;
    }

测试

代码语言:javascript
复制
[Fact]
    public async Task Test1()
    {
        // Arrange
        var store = new Mock<IUserStore<IdentityUser>>();
        store.Setup(x => x.FindByIdAsync("123", CancellationToken.None))
            .ReturnsAsync(new IdentityUser()
            {
                UserName = "test@email.com",
                Id = "123"
            });

        var mgr = new UserManager<IdentityUser>(store.Object, null, null, null, null, null, null, null, null);

        var controller = new SweetController(mgr);

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

        // Assert
        Assert.NotNull(result);
        Assert.Equal("123", result.Id);
    }

我删除了角色检查,只是为了让它尽可能基本地工作。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55412776

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档