我如何单元测试需要UserManager 和SignInManager ?

问题描述 投票:0回答:1
的ASP .NET Core 3.0+ Razor Page处理程序

我正在尝试简单地测试我的Register.cshtml.cs OnGet()方法。 PageModel需要UserManager<TUser>SignInManager<TUser>。我需要模拟需要这些类的SignInManager<TUser>.IsSignedIn(ClaimsPrincipal user)方法。问题在于,ASP .NET Core中那些类的构造函数比以前的ASP .NET版本的大多数解决方案文档要复杂得多。 UserManager的唯一构造函数有9个必需参数,我相信SignInManager需要7个参数。

我有足够的能力执行我的测试,但是模拟方法没有执行。

我的测试:

[Fact]
public void OnGet_UserIsSignedIn_RedirectsToIndex()
{
    using (var testContext = new ApplicationDbContext(TestHelper.TestApplicationDbContextOptions()))
    {
        // Arrange
        var mockUserStore = new Mock<IUserStore<AppUser>>();

        var userManager = new UserManager<AppUser>(mockUserStore.Object,  null, null, null, null, null, null, null, null);

        var mockSignInManager = new Mock<SignInManager<AppUser>>(
            userManager,
            new HttpContextAccessor(),
            new Mock<IUserClaimsPrincipalFactory<AppUser>>().Object,
            new Mock<IOptions<IdentityOptions>>().Object,
            new Mock<ILogger<SignInManager<AppUser>>>().Object,
            new Mock<IAuthenticationSchemeProvider>().Object,
            new Mock<IUserConfirmation<AppUser>>().Object
            );

        var claimsPrincipal = new TestPrincipal(new Claim("name", "John Doe"));
        var _mockConfig = new Mock<IConfiguration>();
        var _mockUserValidator = new UserValidator<AppUser>();
        var _mockLogger = new Mock<ILogger<RegisterModel>>();
        var _mockEmailSender = new Mock<IEmailSender>();

        var registerModel = new RegisterModel(_mockConfig.Object, userManager, mockSignInManager.Object, _mockUserValidator, _mockLogger.Object, _mockEmailSender.Object);

        mockSignInManager.Setup(m => m.IsSignedIn(claimsPrincipal)).Returns(true);
        var expected = new RedirectToPageResult("/Index");

        // Act
        var result = registerModel.OnGet();

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

}

OnGet方法:

public IActionResult OnGet(string returnUrl = null)
{
    // The test is supposed to result in the code inside of this IF executing
    // but it continues on and fails at CreateGateway() because it is missing
    // dependencies for that method.
    if (_signInManager.IsSignedIn(User))
        return new RedirectToPageResult("/Index");

    ReturnUrl = returnUrl;

    // Create gateway
    Gateway = CreateGateway();

    // Load clientToken
    ClientToken = Gateway.ClientToken.Generate();

    return Page();
}

错误:

Error Message:
   System.NullReferenceException : Object reference not set to an instance of an object.
  Stack Trace:
     at Project.Areas.Identity.Pages.Account.RegisterModel.CreateGateway() in ... line 150

RegisterModel构造函数:

public RegisterModel(
    IConfiguration config,
    UserManager<AppUser> userManager,
    SignInManager<AppUser> signInManager,
    UserValidator<AppUser> userValidator,
    ILogger<RegisterModel> logger,
    IEmailSender emailSender)
{
    _config = config;
    _userManager = userManager;
    _signInManager = signInManager;
    _userValidator = userValidator;
    _logger = logger;
    _emailSender = emailSender;
}

不仅我的测试感到过于复杂,而且由于无法依赖CreateGateway()方法,它无法触发IsSignedIn()模拟方法,并且在以后的一行中失败。

简而言之:如何为ASP .NET Core 3.0或更高版本]的[UserManager<TUser>SignInManager<TUser>要求的PageModel处理程序安排测试?] >>

我正在尝试简单地测试Register.cshtml.cs OnGet()方法。 PageModel需要UserManager 和SignInManager 。我需要模拟SignInManager ....

c# unit-testing asp.net-core razor-pages
1个回答
1
投票

在这种情况下,问题在于被测代码中的User

if (_signInManager.IsSignedIn(User))
© www.soinside.com 2019 - 2024. All rights reserved.