Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I UnitTest a custom ActionFilter?

I've been trying to find some straightforward information on this, but I haven't been able to - either what I've found has been to vague for me to understand what's going on, or too specific for the wrong thing, for example a tutorial I found for unit testing an AuthorizeAttribute. (A third alternative is of course that I'm too dumb to realize that I'm reading the information I'm looking for... in which case I still need help, because I'm dumb :P)

I'd like to be able to test two things:

  1. That a given ActionFilter is applied to an action (to make sure that the action meets requirements)
  2. That a given ActionFilter does what it's supposed to do.

And I'm clueless. Could anyone push me in the right direction as to what I actually need to test? What should my Arrange, Act and Assert sections of the tests contain?


A little detail, if I'm not clear enough:

I have a CustomValidationFilter that is supposed to check if two submitted form values are the same, and add a ModelStateError if not. I want to verify that the error is added with the correct error message if the values are not the same, and that the error is not added if the values are equal (and non-null).

I also have a Write action on a GuestbookController. I want to verify that the filter is applied to this action.

like image 938
Tomas Aschan Avatar asked Jun 01 '09 15:06

Tomas Aschan


1 Answers

Using reflection in your test.

   var method = typeof(MyController).GetMethod("MyMethod");
   var attribute = method.GetCustomAttributes(typeof(CustomValidationFilter),false);
                         .Cast<CustomValidationFilter>()
                         .SingleOrDefault();

   Assert.IsNotNull( attribute );
   Assert.AreEqual( "value", atttribute.SomeProperty );

Create a unit test for the method in your class. Mock up the filterContext with the appropriate data and check that whatever variables the method is supposed to set, are in fact what you expect them to be.

 public void AttributeTest()
 {
     var httpContext = MockRepository.GenerateMock<HttpContextBase>();
     var controller = new FakeController();
     controller.controllerContext = new ControllerContext( httpContext, new RouteData(), controller );
     ...

     attribute.OnActionExecuting( filterContext );

     Assert...

 }
like image 196
tvanfosson Avatar answered Sep 20 '22 12:09

tvanfosson