views:

272

answers:

2

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.

A: 

Here's a blog post that describes how to extend and unit test a custom Authorize filter. The blog post details both of your concerns, namely how to test that a given ActionFilter is applied to an action as well as how to test that the ActionFilter does what it is supposed to do.

http://blog.geniar.com/index.php/2009/05/aspnet-mvc-testing-a-custom-authorize-filters/

Praveen Angyan
+3  A: 

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...

 }
tvanfosson
Huge thanks! It took me a while to figure out how to mock up all I needed for the AttributeTest, but I think I got it now. If anyone finds this and is interested, I'll post the code in an edit - just comment here and I'll update the question with my test code.
Tomas Lycken
@Tomas I'd be interested in a post with what exactly you did as I was just crafting a question to ask. That said can you use MvcContrib.TestHelper to assist with mocking up the required data?
ahsteele
@ahsteele: It's been a while since I worked on this now, but it seems I added a working example to http://snipplr.com/users/RockinForGod/ If that isn't enough for you, you can always ask a new question detailing what further needs you have.
Tomas Lycken