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.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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:
1
2
3
4
5
6
7
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

Extending cshtml with functions and properties