Asp.Net MVC Unit Testing Authorization
Asp.Net provides the Authorize attribute for checking to make sure you have an authenticated user and that they are in the correct role(s). Since this is part of the framework, I don’t need to test the attribute (that’s Microsoft’s job). I do want to test that I have applied the attribute with the correct properties.
Here’s my unit test code for checking that the attribute has been applied.
[TestMethod()] public void Autorization_Attributes_Have_Been_Applied() { MethodInfo[] methodInfos = typeof(CustomersController).GetMethods(BindingFlags.Public | BindingFlags.Static); foreach (MethodInfo methodInfo in methodInfos) { ParameterInfo[] parmInfo = methodInfo.GetParameters(); if (methodInfo.Name == "Create" | methodInfo.Name == "Edit") { var attributes = methodInfo.GetCustomAttributes(typeof(AuthorizeAttribute), true); Assert.IsNotNull(attributes); Assert.AreEqual(1, attributes.Length); var authorizeAttribute = (AuthorizeAttribute)attributes[0]; Assert.IsTrue(authorizeAttribute.Roles.Contains(ApplicationRoles.ChangeCustomersGroup)); } if (methodInfo.Name == "Index") { var attributes = methodInfo.GetCustomAttributes(typeof(AuthorizeAttribute), true); Assert.IsNotNull(attributes); Assert.AreEqual(1, attributes.Length); var authorizeAttribute = (AuthorizeAttribute)attributes[0]; Assert.IsTrue(authorizeAttribute.Roles.Contains(ApplicationRoles.ViewCustomersGroup)); } } }
Depending on how much you need to test, you can make sure that only specific roles are applied, etc. My sample above only checks for the Index, Create and Edit methods and allows all others to fall through. You could make it fail so that any public method that wasn’t checked failed the test. Remember, if it’s public on your controller it can be called.
Update: April 1, 2010 -- Josh has taken this to the next step. Check it out here.
Comments
Thanks again.