Moq 不会调用 IAuthenticationManager 登录方法



我正在尝试通过验证身份验证管理器登录方法是否已调用一次来运行单元测试以成功登录 这是我收到的错误:

消息:引发异常Portfolio.UnitTest.WebUI.Controllers.LoginControllerTests.Login_Verified_Authenticates_System_User测试方法: 最小起订量模拟异常: 模拟的预期调用一次,但为 0 次:m => m.SignIn(AuthenticationProperties, [ClaimIdentity](

配置的设置: m => m.SignIn(AuthenticationProperties, [ClaimIdentity](

执行的调用: IAuthenticationManager.SignIn(AuthenticationProperties, [ClaimsIdentity](

甚至错误消息似乎也自相矛盾。

我的控制器类/方法:

public class LoginController : ProjectBaseController
{
private IAuthenticationManager _authenticationManager;
    public IAuthenticationManager AuthenticationManager
    {
        get
        {
            return _authenticationManager ?? HttpContext.GetOwinContext().Authentication;
        }
        set
        {
            _authenticationManager = value;
        }
    }
[HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult Index(LoginViewModel accountUser)
    {
        if (!ModelState.IsValid)
            return View(accountUser);
        var systemUser = _authenticationService.Verify(accountUser.Email, accountUser.Password);
        if (systemUser == null)
        {
            ModelState.AddModelError("", "Invalid email address or password");
            return View(accountUser);
        }
        var identity = new ClaimsIdentity
        (
            new[] 
            {
                new Claim(ClaimTypes.Name, systemUser.FullName),
                new Claim(ClaimTypes.Email, systemUser.Email)
            },
            DefaultAuthenticationTypes.ApplicationCookie,
            ClaimTypes.Name, 
            ClaimTypes.Role
        );
        // Set roles for authorization attributes used throughout dashboard
        foreach(var role in systemUser.Roles)
        {
            identity.AddClaim(new Claim(ClaimTypes.Role, role.Name));
        }
        AuthenticationManager.SignIn
        (
            new AuthenticationProperties
            {
                IsPersistent = true
            }, 
            identity
        );
        return Redirect(accountUser.ReturnUrl);   
    }

登录控制器测试:

[TestClass]
public class LoginControllerTests
{
    private readonly Mock<IAuthenticationManager> _mockAuthenticationManager;
    private readonly Mock<IAuthenticationService> _mockAuthenticationService;
    public LoginControllerTests()
    {
        _mockAuthenticationManager = new Mock<IAuthenticationManager>();
        _mockAuthenticationService = new Mock<IAuthenticationService>();
    }
    private LoginController GetLoginControllerInstance()
    {
        var controller = new LoginController(_mockAuthenticationService.Object);
        controller.AuthenticationManager = _mockAuthenticationManager.Object;
        return controller;
    }
    [TestMethod]
    public void Login_Verified_Authenticates_System_User()
    {
        // Arrange
        var viewModel = new LoginViewModel("/")
        {
            Email = "email@test.co.uk",
            Password = "password-test"
        };
        var systemUser = new SystemUser()
        {
            Id = new Random().Next(),
            FirstName = "Joe",
            LastName = "Bloggs",
            Email = viewModel.Email,
            Password = viewModel.Password,
            Roles = new List<Role>()
        };
        var identity = new ClaimsIdentity
        (
            new[]
            {
                new Claim(ClaimTypes.Name, systemUser.FullName),
                new Claim(ClaimTypes.Email, systemUser.Email)
            },
            DefaultAuthenticationTypes.ApplicationCookie,
            ClaimTypes.Name,
            ClaimTypes.Role
        );
        var authenticationProperty = new AuthenticationProperties
        {
            IsPersistent = true
        };
        var controller = this.GetLoginControllerInstance();
        _mockAuthenticationService.Setup(m => m.Verify(viewModel.Email, viewModel.Password))
            .Returns(systemUser);
        _mockAuthenticationManager.Setup(m => m.SignIn(authenticationProperty, identity));
        // Act
        var result = controller.Index(viewModel);
        // Assert
        Assert.IsNotNull(result);
        Assert.IsTrue(controller.ModelState.IsValid);
        _mockAuthenticationService.Verify(m => m.Verify(viewModel.Email, viewModel.Password), Times.Once);
        _mockAuthenticationManager.Verify(m => m.SignIn(authenticationProperty, identity), Times.Once);
    }
}
}

在 deubg 中运行该方法可以在控制器中调用,但 Moq 似乎忽略了它。

有什么想法吗?

Nkosi在对你的问题的评论中说:

在表达式中

m => m.SignIn(authenticationProperty, identity)

authenticationPropertyidentity两个参数必须与实际传入的两个参数(由测试系统传递("相等"。那么,当你比较时,Equals会返回真吗?

如果需要,您可以使用It.IsAny<AuthenticationProperties>()It.Is((AuthenticationProperties x) => x.IsPersistent)或类似功能。类似于ClaimsIdentity.那么最小起订量将不再需要Equals平等。

相关内容

  • 没有找到相关文章

最新更新