【问题标题】:Unit test anonymous user against controller with authorize attribute针对具有授权属性的控制器对匿名用户进行单元测试
【发布时间】:2014-07-29 12:10:53
【问题描述】:

我正在尝试构建单元测试以确保未经身份验证的用户无法访问控制器。当我运行测试时,发现用户已通过身份验证。我如何模拟事情,以便测试发现模拟用户未经身份验证。

我正在使用带有 indentity 2.0 的 mvc5

控制器

[Authorize]
public class ProfileController : Controller
{
    private ICompanyServiceLayer _service;

    public ProfileController(ICompanyServiceLayer service)
    {
        _service = service;
    }

    public ActionResult Index(int id)
    {
            /* cool stuff happens here */
        return View();
    }
}

测试

[Test]
public void Index_As_Annonymous_User()
{
    // arrange
    Mock<ICompanyServiceLayer> service = new Mock<ICompanyServiceLayer>();

    GenericIdentity id = new GenericIdentity("");
    Mock<IPrincipal> princ = new Mock<IPrincipal>();
    princ.Setup(x => x.Identity).Returns(id);


    Mock<HttpContextBase> contextBase = new Mock<HttpContextBase>();
    contextBase.Setup(x => x.User).Returns(princ.Object);

    Mock<ControllerContext> controllerContext = new Mock<ControllerContext>();
    controllerContext.Setup(x => x.HttpContext).Returns(contextBase.Object);

    // controller            
    ProfileController controller = new ProfileController(service.Object);
    controller.ControllerContext = controllerContext.Object;

    // act
    var result = controller.Index(1);

    // assert
    Assert.IsInstanceOf(typeof(HttpStatusCodeResult), result);
}

根据 blorkfish 建议更新

[Test]
public void Index_As_Annonymous_User()
{
    // arrange
    Mock<ICompanyServiceLayer> service = new Mock<ICompanyServiceLayer>();

    Mock<HttpRequestBase> request = new Mock<HttpRequestBase>();
    request.Setup(x => x.IsAuthenticated).Returns(false);

    Mock<HttpContextBase> contextBase = new Mock<HttpContextBase>();
    contextBase.Setup(x => x.Request).Returns(request.Object);

    // controller            
    ProfileController controller = new ProfileController(service.Object);
    controller.ControllerContext = new ControllerContext(contextBase.Object, new RouteData(), controller);

    // act
    var result = controller.Index(1);

    // assert
    Assert.IsInstanceOf(typeof(HttpStatusCodeResult), result);
}

【问题讨论】:

    标签: unit-testing asp.net-mvc-5


    【解决方案1】:

    使用 Moq,您需要模拟 HttpContextBase 并确保其 IsAuthenticated 属性返回 false。

       var mockHttpContext = new Mock<HttpContextBase>();
    
            mockHttpContext.SetupGet(c => c.User.Identity.IsAuthenticated).Returns(false);
    
            var mockControllerContext = new Mock<ControllerContext>();
    
            mockControllerContext.Setup(c => c.HttpContext).Returns(mockHttpContext.Object);
    
            controller.ControllerContext = mockControllerContext.Object;
    

    然后,在控制器操作中运行以下命令应该返回 false:

    User.Identity.IsAuthenticated

    【讨论】:

      【解决方案2】:

      mvc 框架检查 HttpRequest.IsAuthenticated 标志。要模拟这个,你需要模拟 httpContext 和 httpRequest:

      var httpContext = MockRepository.GenerateMock<HttpContextBase>();
      var httpRequest = MockRepository.GenerateMock<HttpRequestBase>();
      
      httpContext.Stub(x => x.Request).Return(httpRequest);
      httpRequest.Stub(x => x.IsAuthenticated).Return(false);
      
      UserController controller = new UserController();
      controller.ControllerContext 
          = new ControllerContext(httpContext, new RouteData(), controller);
      

      【讨论】:

      • 试过了,Index内的代码还在执行中。
      • 不模拟身份主体,您将得到空值
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-20
      • 1970-01-01
      • 2012-08-29
      • 2018-09-29
      • 2017-04-26
      相关资源
      最近更新 更多