模拟SignInManager [英] Mocking a SignInManager

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

问题描述

使用Moq和xUnit进行单元测试的新手。我正在尝试模拟控制器构造函数中用于构建单元测试的SignInManager。我能找到的SignInManager构造函数的文档说明它接受UserManagerAuthenticationManager对象:https://msdn.microsoft.com/en-us/library/mt173769(v=vs.108).aspx#M:Microsoft.AspNet.Identity.Owin.SignInManager`2.

当我尝试模拟控制器时,收到错误消息,指出它无法实例化SignInManagerAuthenticationManager类的代理。

错误:

消息: Castle.DynamicProxy.InvalidProxyConstructorArgumentsException:可以 未实例化类的代理: Microsoft.AspNetCore.Identity.SignInManager1[[Models.AppUser, ,版本=1.0.0.0,区域性=中性, PublicKeyToken=空]]。找不到匹配的构造函数 给定参数:Castle.Proxies.UserManager`1Proxy Castle.Proxies.AuthenticationManagerProxy"

单元测试:

public void Can_Send_Password_Reset_Email()
{
    //Arrange
    //create mock services
    Mock<IEmailService> mockEmailService = new Mock<IEmailService>();
    Mock<ILessonRepository> mockRepo = new Mock<ILessonRepository>();
    Mock<UserManager<AppUser>> mockUsrMgr = GetMockUserManager();
    var mockSignInMgr = GetMockSignInManager();
    Mock<UserValidator<AppUser>> mockUsrVal = new Mock<UserValidator<AppUser>>();
    Mock<PasswordValidator<AppUser>> mockPwdVal = new Mock<PasswordValidator<AppUser>>();
    Mock<PasswordHasher<AppUser>> mockPwdHshr = new Mock<PasswordHasher<AppUser>>();
    Mock<ForgotPasswordModel> model = new Mock<ForgotPasswordModel>();
    model.Object.Email = "joe@example.com";

    var user = new AppUser();
    var token = mockUsrMgr.Object.GeneratePasswordResetTokenAsync(user).Result;

    //create mock temporary data, needed for controller message
    Mock<ITempDataDictionary> tempData = new Mock<ITempDataDictionary>();
    //create the controller
    //ERROR ON THIS LINE
    AccountController controller = new AccountController(mockUsrMgr.Object, mockSignInMgr.Object, mockUsrVal.Object, mockPwdVal.Object, mockPwdHshr.Object, mockEmailService.Object)
    {
        TempData = tempData.Object
    };

    //Act
    //the controller should call the email action method
    controller.PasswordResetEmail(model.Object);

    //Assert
    //verify that the email service method was called one time
    mockEmailService.Verify(m => m.PasswordResetMessage(user, "Test Email"), Times.Once());
}

SignInManager模拟函数:

//create a mock SignInManager class
private Mock<SignInManager<AppUser>> GetMockSignInManager()
{
    var mockUsrMgr = GetMockUserManager();
    var mockAuthMgr = new Mock<AuthenticationManager>();
    return new Mock<SignInManager<AppUser>>(mockUsrMgr.Object, mockAuthMgr.Object);
}

GetMockUserManager()在其他单元测试中运行良好,似乎不是问题所在。

推荐答案

我就是这么做的,希望这对您有帮助。

public class FakeSignInManager : SignInManager<ApplicationUser>
{
    public FakeSignInManager()
            : base(new FakeUserManager(),
                 new Mock<IHttpContextAccessor>().Object,
                 new Mock<IUserClaimsPrincipalFactory<ApplicationUser>>().Object,
                 new Mock<IOptions<IdentityOptions>>().Object,
                 new Mock<ILogger<SignInManager<ApplicationUser>>>().Object,
                 new Mock<IAuthenticationSchemeProvider>().Object)
        { }        
}



public class FakeUserManager : UserManager<ApplicationUser>
    {
        public FakeUserManager()
            : base(new Mock<IUserStore<ApplicationUser>>().Object,
              new Mock<IOptions<IdentityOptions>>().Object,
              new Mock<IPasswordHasher<ApplicationUser>>().Object,
              new IUserValidator<ApplicationUser>[0],
              new IPasswordValidator<ApplicationUser>[0],
              new Mock<ILookupNormalizer>().Object,
              new Mock<IdentityErrorDescriber>().Object,
              new Mock<IServiceProvider>().Object,
              new Mock<ILogger<UserManager<ApplicationUser>>>().Object)
        { }

        public override Task<IdentityResult> CreateAsync(ApplicationUser user, string password)
        {
            return Task.FromResult(IdentityResult.Success);
        }

        public override Task<IdentityResult> AddToRoleAsync(ApplicationUser user, string role)
        {
            return Task.FromResult(IdentityResult.Success);
        }

        public override Task<string> GenerateEmailConfirmationTokenAsync(ApplicationUser user)
        {
            return Task.FromResult(Guid.NewGuid().ToString());
        }

    }

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

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