简体   繁体   中英

AuthorizeAttribute unit testing dependency injection

I am aiming to create a custom implementation of MVC's IAuthorizationFilter by subclassing AuthorizeAttribute and overriding bool AuthorizeCore(HttpContextBase httpContext);

Being the hipster I am, I want to do this TDD style.
(Just because I said I'm a hipster doesn't mean you can navigate back. Yes, I saw that.)

Additionally, I want to inject into certain parameters of the constructor, using ninject like so .

So, my question is how do I unit test such a setup?

Here is my Attribute setup:

public class MyAuthorize : FilterAttribute {

    public MyAuthorize(params string[] Activities)
    {
        this.RequestedActivities = Activities.ToList();
    }
    public IEnumerable<string> RequestedActivities { get; set; }
}

public class MyAuthorizeFilter : AuthorizeAttribute
{
    private readonly IEnumerable<string> _RequestingActivities;
    private readonly IUserService _UserService;

    public MyAuthorizeFilter(IUserService UserService, IEnumerable<string> Activities) 
    {
        this._RequestingActivities = Activities;
        _UserService = UserService;
    }

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        return (_RequestingActivities.All(c=>c == "Permitted"));
    }
}

I attempted to test the void OnAuthorization(AuthorizationContext filterContext); method exposed by AuthorizeAttribute but there wasn't anything to assert against. filterContext was not altered in any noticeable way.

My next step was to create a mock class with [MyAuthorize("APermission")] on an action, then invoke that like so:

controller.ActionInvoker.InvokeAction(controller.ControllerContext, "Permitted");

But since I'm not actually using MyAuthorizeFilter it's not calling the code that actually does the authorization checks.

I honestly have no idea how to proceed.

Remember, when you unit test, you're not testing the implementation of things like attributes being hooked up and being called. You're testing the actual attribute's functionality.

So all you need to do is instantiate you MyAuthorize class, probably passing in mocked services and activities. Then you simply call the methods that will get called by the framework, and verify that the proper results are achieved.

In this case, you would probably just call MyAuthorize.OnAuthorization() passing in a mocked authorization context, and check the state of the filterContext.Response object, which will be unchanged if it succeeds and will contain an Unauthorized (401) if it fails.

It may also throw exceptions if the filterContext is null or not configured correctly.

You can look at the source code to the AuthorizeAttribute to see what it's doing.. so you know what to assert against.

http://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/AuthorizeAttribute.cs

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM