Testing controller actions with ActionFilterAttribute in ASP .NET MVC

Hey,
Have you ever wanted to test your controller actions with the logic you add with ActionFilterAttributes?
Well, I did.
So I wrote this helper class, which executes the ActionFilterAttribute methods.
public class FilterAttributeTester
{
    public ActionExecutingContext ExecuteOnActionExecuting<TAttribute>(Controller aController, Func<ActionResult> aAction)
     where TAttribute : ActionFilterAttribute
    {
        var actionExecutingContext = CreateActionExecutingContext(aController, aAction);

        var attribute = GetAttribute<TAttribute>(aAction);
        attribute.OnActionExecuting(actionExecutingContext);
        return actionExecutingContext;
    }

    public ActionExecutedContext ExecuteOnActionExecuted<TAttribute>(Controller aController, Func<ActionResult> aAction)
     where TAttribute : ActionFilterAttribute
    {
        var actionExecutedContext = CreateActionExecutedContext(aController, aAction);

        var attribute = GetAttribute<TAttribute>(aAction);
        attribute.OnActionExecuted(actionExecutedContext);
        return actionExecutedContext;
    }

    public static ActionExecutingContext CreateActionExecutingContext(Controller aController, Func<ActionResult> aAction)
    {
        return new ActionExecutingContext(
           new ControllerContext(new HttpContextWrapper(HttpContext.Current), new RouteData(), aController),
           new ReflectedActionDescriptor(aAction.Method, aAction.Method.Name, new ReflectedControllerDescriptor(aController.GetType())),
           new Dictionary<string, object>());
    }

    public static ActionExecutedContext CreateActionExecutedContext(Controller aController, Func<ActionResult> aAction)
    {
        return new ActionExecutedContext(
           new ControllerContext(new HttpContextWrapper(HttpContext.Current), new RouteData(), aController),
           new ReflectedActionDescriptor(aAction.Method, aAction.Method.Name, new ReflectedControllerDescriptor(aController.GetType())),
           false,
           null);
    }

    private static TAttribute GetAttribute<TAttribute>(Func<ActionResult> aAction) where TAttribute : ActionFilterAttribute
    {
        return aAction.Method.GetCustomAttributes(typeof(TAttribute), true).Select(x => x as TAttribute).SingleOrDefault();
    }
}
And that's it!
In your test add the following code:
var filterAttributeTester = new FilterAttributeTester();
var actionExecutingContext = filterAttributeTester.ExecuteOnActionExecuting<UserLoggedInAttribute>(homepageController, homepageController.Index);
var returnValue = actionExecutingContext.Result as RedirectResult;
if (returnValue != null)
{
 // filter attribute redirected to another action
}
All you have to do is fake HttpContext, and you're good!

Good luck!

Comments

  1. I would like to say thank you for the amazing details and concepts you are sharing in this.The style of writing is excellent and also the content is top-notch

    I would like to say thank you for the amazing details and concepts you are sharing in this.The style of writing is excellent and also the content is top-notch

    ReplyDelete

Post a Comment

Popular posts from this blog

Impersonating CurrentUser from SYSTEM

Add Styles & Scripts Dynamically to head tag in ASP .NET MVC

Json To Dictionary generic model binder