我如何模拟UserManager和RoleManager进行单元测试 [英] How do i mock UserManager and RoleManager for unit test

查看:109
本文介绍了我如何模拟UserManager和RoleManager进行单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我模拟了抽象类,以测试类的具体方法,如下所示.

I have mocked abstract class to test concrete method of a class as following.

var mock = new Mock<BaseTestController>();
mock.CallBase = true;
var ta = mock.Object;

ta.ControllerContext = new HttpControllerContext { Request = new HttpRequestMessage() };          
var owinMock = new Mock<IOwinContext>();
owinMock.Setup(o => o.Authentication.User).Returns(new ClaimsPrincipal());
owinMock.Setup(o => o.Request).Returns(new Mock<OwinRequest>().Object);
owinMock.Setup(o => o.Response).Returns(new Mock<OwinResponse>().Object);
owinMock.Setup(o => o.Environment).Returns(new Dictionary<string, object> { { "key1", 123 } });
var traceMock = new Mock<TextWriter>();
owinMock.Setup(o => o.TraceOutput).Returns(traceMock.Object);

ta.Request.SetOwinContext(owinMock.Object);
var result = await ta.ActivateDeactive("test@user.com", true);

问题:我的抽象类使用 Entity Framework 6和Asp.Net Identity UserManager和RoleManager 如下

Problem: My abstract class use Entity Framework 6 and Asp.Net Identity UserManager and RoleManager as following

public TestUserManager UserService
{
    get
    {
        return _userService ?? Request.GetOwinContext().GetUserManager<TestUserManager>();
    }

    private set
    {
        _userService = value;
    }
}

public TestRoleManager RoleService
{
    get
    {
        return _roleService ?? Request.GetOwinContext().Get<TestRoleManager>();
    }

    private set
    {
        _roleService = value;
    }
}

如何在上面的模拟代码中模拟 TestUserManager和TestRoleManager ?

How i can mock TestUserManager and TestRoleManager in my above mocking code?

我尝试了以下方法,但无法将其与controllerContext挂钩.

I tried the following way but couldn't get the way to hook it up with controllerContext.

var userStore = new Mock<IUserStore<TestUser>>();
var userManager = new TestUserManager(userStore.Object);

下面由Aleksey L提出的问题的答案.

Answer to question asked below by Aleksey L.

这是 TestUserManager 派生 UserManaer 并实现的方式.

This is how TestUserManager derives UserManaer and implement.

public class TestUserManager : UserManager<TestUser>
{
    public TestUserManager(IUserStore<TestUser> store)
        : base(store)
    {
    }
    public static TestUserManager Create(IdentityFactoryOptions<TestUserManager> options, IOwinContext context)
    {
        TestUserManager manager = new TestUserManager(new UserStore<TestUser>(context.Get<AuthContext>()));
        setValidationRules(manager);

        IDataProtectionProvider dataProtectionProvider = options.DataProtectionProvider;
        if (dataProtectionProvider == null)
            dataProtectionProvider = new DpapiDataProtectionProvider();
         manager.UserTokenProvider = new DataProtectorTokenProvider<TestUser>(dataProtectionProvider.Create("ASP.NET Identity")) { TokenLifespan = TimeSpan.FromDays(expiryTime) };

        return manager;
    }

    public static TestUserManager CreateLocal(AuthContext context)
    {
        TestUserManager manager = new TestUserManager(new UserStore<TestUser>(context));
        setValidationRules(manager);

        IDataProtectionProvider dataProtectionProvider = new DpapiDataProtectionProvider();
        manager.UserTokenProvider = new DataProtectorTokenProvider<TestUser>(dataProtectionProvider.Create("ASP.NET Identity"));

        return manager;
    }

    private static void setValidationRules(ApplicationUserManager manager)
    {
        manager.UserValidator = new UserValidator<TestUser>(manager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true
        };

        manager.PasswordValidator = new ApplicationPasswordValidator
        {
            RequiredLength = 30,
            MaximumCharacters = 30,
            RequireNonLetterOrDigit = false,
            RequireDigit = true,
            RequireLowercase = false,
            RequireUppercase = false
        };
    }
}

控制器代码

public async Task<IHttpActionResult> ActivateDeactive(string studentId, bool active)
{
    IdentityResult result;
    _accountService = new AccountMgtService(UserService, RoleService);
    result = await _accountService.ActiveDeactiveUser(userId, active);

}

推荐答案

不知道为什么要实现 TestUserManager 而不只是模拟它.不好意思,我们在控制器中有以下代码:

Not sure why you're implementing TestUserManager and not just mocking it. Lat's say we have following code in controller:

var owinContext = Request.GetOwinContext();
var userManager = owinContext.GetUserManager<ApplicationUserManager>();
var applicationUser = userManager.FindById("testId");

您可以通过以下方式注入模拟用户存储:

You can inject mock user store this way:

var owinMock = new Mock<IOwinContext>();

var userStoreMock = new Mock<IUserStore<ApplicationUser>>();
userStoreMock.Setup(s => s.FindByIdAsync("testId")).ReturnsAsync(new ApplicationUser
{
    Id = "testId",
    Email = "test@email.com"
});
var applicationUserManager = new ApplicationUserManager(userStoreMock.Object);

owinMock.Setup(o => o.Get<ApplicationUserManager>(It.IsAny<string>())).Returns(applicationUserManager);

ta.Request.SetOwinContext(owinMock.Object);

这篇关于我如何模拟UserManager和RoleManager进行单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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