Reputation: 6478
I would like to perform an audit as part of a unit test that uses reflection to verify some assumptions, the basic-psuedo code for this would be as follows:
For each class in a given assembly, locate the controller classes (ASP.NET MVC2).
For each action in this class,
locate any that are decorated with a
given attribute (lets call this
TargetAttribute
)
For each of these methods decorated
with the attribute of interest,
ensure that at least one of the
action method's parameters implements a given
interface (let's call this
ITarget
).
How would I go about performing such a check? (answers in C# or VB.NET are welcome)
Edit:
I am posting the final code here (translated to VB.NET) that performs this check:
Dim ass As Assembly = Assembly.GetAssembly(GetType(Web.WebConfiguratorMarker))
Dim methodsToCheck = ass.GetTypes().
Where(Function(t) t.IsSubclassOf(GetType(Controller))).
SelectMany(Function(t) t.GetMethods()).
Where(Function(m) m.GetCustomAttributes(GetType(AutoValidateJsonModelAttribute), False).Length > 0).
Where(Function(m) m.ReturnType Is GetType(ActionResult)).ToArray()
For Each method In methodsToCheck
Dim implementsIValidatable As Boolean = False
For Each param In method.GetParameters()
If GetType(IValidatable).IsAssignableFrom(param.ParameterType) Then
implementsIValidatable = True
Exit For
End If
Next
Assert.True(implementsIValidatable, String.Format("Controller of type [{0}] has an action [{1}] that is decorated with <AutoValidateJsonModel()> but does not have a IValidatable instance as a param", method.DeclaringType, method.Name))
Next
Upvotes: 2
Views: 478
Reputation: 1
Your auditing is a lot of trouble for a unit test that will probably not help with code quality. MVC is supposed to be better for unit testing but unit tests are not helpful. Web Forms is much better at everything else besides unit testing, so it is a better choice for enterprise applications.
Upvotes: 0
Reputation: 6376
var assembly = System.Reflection.Assembly.GetExecutingAssembly();
var methods = assembly.GetTypes()
.Where(t => t is System.Web.Mvc.Controller)
.SelectMany(t => t.GetMethods())
.Where(m => m.ReturnType is ActionResult)
.Where(m => m.GetCustomAttributes(typeof(TargetAttribute), false).Length > 0)
.ToArray();
bool implementsITarget = false;
foreach(method in methods)
{
foreach(param in method.GetParameters())
{
if(param.ParameterType is ITarget)
{
implementsITarget = true;
break;
}
}
Assert.True(implementsITarget , String.Format("Controller {0} has action {1} that does not implement ITarget but is decorated with TargetAttribute", method.DeclaringType, method.Name) );
implementsITarget = false;
}
Upvotes: 2