测试自定义AuthorizationAttribute时抛出NullReferenceException

我看了一下:

  • 如何进行单元测试以测试检查请求标头的方法?
  • 如何使用moq模拟Controller.User
  • 如何单元测试具有[Authorize]属性的控制器方法?
  • 我试图测试我写的一个自定义的AuthorizeAttribute。

    我已经尝试了许多不同的事情来实现它。 这是我目前的尝试。

    [AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = true)]
    public class ConfigurableAuthorizeAttribute : AuthorizeAttribute
    {
        private Logger log = new Logger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        private IRoleHelper roleHelper;
    
        public ConfigurableAuthorizeAttribute()            
        {
            roleHelper = new ADRoleHelper();
        }
    
        public ConfigurableAuthorizeAttribute(IRoleHelper roleHelper)            
        {
            this.roleHelper = roleHelper;
        }
    
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (!httpContext.User.Identity.IsAuthenticated)
            {
                return false;
            }
    
            if (this.roleHelper.IsUserInRole(this.Roles, HttpContext.Current.User.Identity.Name))
            {
                return true;
            }
    
            return false;
        }
    
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            base.HandleUnauthorizedRequest(filterContext);
            filterContext.Result = new RedirectResult("~/home/Unauthorized");            
        }
    
    
    }
    
    [Test]
    public void unauthenticated_user_not_allowed_to_access_resource()
    {
        var user = new Mock<IPrincipal>();
        user.Setup(u => u.Identity.IsAuthenticated).Returns(false);
    
        var authContext = new Mock<AuthorizationContext>();
        authContext.Setup(ac => ac.HttpContext.User).Returns(user.Object);
    
        var configAtt = new ConfigurableAuthorizeAttribute();
        configAtt.OnAuthorization(authContext.Object);
    
        authContext.Verify(ac => ac.Result == It.Is<RedirectResult>(r => r.Url == ""));
    }
    

    无论我做什么,在运行测试时总会得到System.NullReferenceException。 它似乎永远不会通过OnAuthorization调用。 堆栈跟踪如下所示:

    结果消息:System.NullReferenceException:未将对象引用设置为对象的实例。 结果StackTrace:System.Web.Mvc.OutputCacheAttribute.GetChildActionFilterFinishCallback(ControllerContext controllerContext)at System.Web.Mvc.AuthorizeAttribute.OnAuthorization(AuthorizationContext filterContext)at ... ConfigurableAuthorizeAttributeTests.unauthenticated_user_not_allowed_to_access_resource()in ... ConfigurableAuthorizeAttributeTests.cs:line 29

    有没有人对如何解决这个问题有任何想法?

    编辑

    我找到了解决方案。 我还需要模拟ControllerDescriptor并确保HttpContextBase.Items返回一个新的Dictionary。

    工作代码:

    var context = new Mock<HttpContextBase>();
    context.Setup(c => c.Items).Returns(new Dictionary<object, object>());
    context.Setup(c => c.User.Identity.IsAuthenticated).Returns(false);
    var controller = new Mock<ControllerBase>();
    
    var actionDescriptor = new Mock<ActionDescriptor>();
    actionDescriptor.Setup(a => a.ActionName).Returns("Index");
    var controllerDescriptor = new Mock<ControllerDescriptor>();            
    actionDescriptor.Setup(a => a.ControllerDescriptor).Returns(controllerDescriptor.Object);
    
    var controllerContext = new ControllerContext(context.Object, new RouteData(), controller.Object);
    var filterContext = new AuthorizationContext(controllerContext, actionDescriptor.Object);
    var att = new ConfigurableAuthorizeAttribute();
    
    att.OnAuthorization(filterContext);
    
    Assert.That(filterContext.Result, Is.InstanceOf<RedirectResult>());
    Assert.That(((RedirectResult)filterContext.Result).Url, Is.EqualTo("~/home/Unauthorized"));
    

    我找到了解决方案。 我还需要模拟ControllerDescriptor并确保HttpContextBase.Items返回一个新的Dictionary。

    工作代码:

    var context = new Mock<HttpContextBase>();
    context.Setup(c => c.Items).Returns(new Dictionary<object, object>());
    context.Setup(c => c.User.Identity.IsAuthenticated).Returns(false);
    var controller = new Mock<ControllerBase>();
    
    var actionDescriptor = new Mock<ActionDescriptor>();
    actionDescriptor.Setup(a => a.ActionName).Returns("Index");
    var controllerDescriptor = new Mock<ControllerDescriptor>();            
    actionDescriptor.Setup(a => a.ControllerDescriptor).Returns(controllerDescriptor.Object);
    
    var controllerContext = new ControllerContext(context.Object, new RouteData(), controller.Object);
    var filterContext = new AuthorizationContext(controllerContext, actionDescriptor.Object);
    var att = new ConfigurableAuthorizeAttribute();
    
    att.OnAuthorization(filterContext);
    
    Assert.That(filterContext.Result, Is.InstanceOf<RedirectResult>());
    Assert.That(((RedirectResult)filterContext.Result).Url, Is.EqualTo("~/home/Unauthorized"));
    
    链接地址: http://www.djcxy.com/p/4805.html

    上一篇: NullReferenceException thrown when testing custom AuthorizationAttribute

    下一篇: NullReferenceException in DbContext.saveChanges()