【问题标题】:How do I stub/mock AuthenticationManager in MVC 6?如何在 MVC 6 中存根/模拟 AuthenticationManager?
【发布时间】:2019-11-22 05:27:10
【问题描述】:

我正在尝试对直接与this.HttpContext.Authentication 交互以进行身份​​验证的 MVC 6 控制器进行单元测试。我没有使用身份框架,而是直接与 Cookie 身份验证中间件交互。

根据 MS 看到的一些示例,我一直在使用 DefaultHttpContext 进行测试。问题是 DefaultHttpContext 上的 AuthenticationManager 属性是只读的,所以我不确定如何模拟它。

如果我不模拟它,我会在调用时在测试中收到一条错误消息,指出“没有配置身份验证处理程序来处理方案:Cookies”:

HttpContext.Authentication.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, claimsPrincipal, authProperties);

【问题讨论】:

  • 这个问题有运气吗?我遇到了类似的问题并试图找到可能的解决方案。

标签: unit-testing authentication mocking asp.net-core asp.net-core-mvc


【解决方案1】:

我遇到了同样的问题,我终于用某种程度的嘲笑做到了 我用起订量

var claimPrincipal = new ClaimsPrincipal();

var mockAuth = new Mock<AuthenticationManager>();
mockAuth.Setup(c => c.SignInAsync("YourScheme", claimPrincipal)).Returns(Task.FromResult("done"));

var mockContext = new Mock<HttpContext>();
            mockContext.Setup(c => c.Authentication).Returns(mockAuth.Object);

var fakeActionContext = new ActionContext(mockContext.Object, new RouteData(), new ControllerActionDescriptor());
var contContext = new ControllerContext(fakeActionContext);

然后您将该控制器上下文传递给您要测试的控制器

 var controller = new TestedController(Your attribute)
 {
       ControllerContext = contContext
  };

【讨论】:

    【解决方案2】:

    MS 现在已弃用接受的答案,建议不要使用 AuthenticationManager 而是使用扩展方法。下面是一个替代方案。请注意,添加的额外两个服务是因为设置 RequestServices 会删除一些默认值,否则这些默认值将由 DefaultHttpContext 创建。

    var context = new ControllerContext();
    context.HttpContext = new DefaultHttpContext();
    context.HttpContext.User = userMock.Object;  // If needed
    context.HttpContext.Session = sessionMock.Object;  // If needed
    
    var authManager = new Mock<IAuthenticationService>();
    authManager.Setup(s => s.SignOutAsync(It.IsAny<HttpContext>(), 
                CookieAuthenticationDefaults.AuthenticationScheme, 
                It.IsAny<Microsoft.AspNetCore.Authentication.AuthenticationProperties>())).
                Returns(Task.FromResult(true));
    var servicesMock = new Mock<IServiceProvider>();
    servicesMock.Setup(sp => sp.GetService(typeof(IAuthenticationService))).Returns(authManager.Object);
    servicesMock.Setup(sp => sp.GetService(typeof(IUrlHelperFactory))).Returns(new UrlHelperFactory());
    servicesMock.Setup(sp => sp.GetService(typeof(ITempDataDictionaryFactory))).Returns(new TempDataDictionaryFactory(new SessionStateTempDataProvider()));
    
    context.HttpContext.RequestServices = servicesMock.Object;
    // Use context to pass to your controller
    

    【讨论】:

      【解决方案3】:

      这就是使用 FakeItEasy 的方法:

      var actionContext = new ActionContext
              {
                  HttpContext = new DefaultHttpContext(),
                  RouteData = new RouteData(),
                  ActionDescriptor = new ControllerActionDescriptor()
              };
      
      // Creating AuthenticationService and Return calls for the Authentication factory
                  var authManager = A.Fake<IAuthenticationService>();
                  var authProperties = new Microsoft.AspNetCore.Authentication.AuthenticationProperties();
                  var servicesMock = A.Fake<IServiceProvider>();
                  A.CallTo(() => authManager.SignOutAsync(actionContext.HttpContext, CookieAuthenticationDefaults.AuthenticationScheme, authProperties)).Returns(Task.FromResult(true));
                  A.CallTo(() => servicesMock.GetService(typeof(IAuthenticationService))).Returns(authManager);
                  A.CallTo(() => servicesMock.GetService(typeof(IUrlHelperFactory))).Returns(new UrlHelperFactory());
                  A.CallTo(() => servicesMock.GetService(typeof(ITempDataDictionaryFactory))).Returns(new TempDataDictionaryFactory(new SessionStateTempDataProvider()));
      
                  var concon = new ControllerContext(actionContext);
                  concon.HttpContext.RequestServices = servicesMock;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-08-23
        • 2014-06-14
        • 1970-01-01
        • 2011-08-01
        • 2010-10-29
        • 2016-04-01
        • 1970-01-01
        • 2014-07-14
        相关资源
        最近更新 更多