I'm working on writing a non-trivial "unit test" (perhaps better called a "UI test"?). In this case, I think I want a test that (reflectively?) finds all appropriate action handlers and then verifies that our SiteMap has a node for those Action Handlers. What I need is to identify when a developer adds a page to our system and forgets to add it to the SiteMap (this seems to be a common problem and I'd like to make it go away, which a test should easily be able to do for us). Ultimately, we want to make sure that any page that a user can land on will have a home in our SiteMap so that it builds the appropriate breadcrumb t开发者_StackOverflow中文版o tell the user where they are in our system (that breadcrumb part already works perfect for us, as long as the page is in the SiteMap). I would much rather try to do this with a test than try to force some policy/procedure update on us that is yet another thing we have to deal with.
Any tips on some existing code to start from in this endeavor? And if not, any thoughts on the best way to do this?
One possibility that I am considering is to reflectively identify any method that is decorated with the AcceptVerbs
attribute which doesn't have a return type of JsonResult
(and perhaps a couple others which would clearly not be "web pages" such as FileResult
). And perhaps limit my search by first identifying classes which inherit System.Web.Mvc.Controller
.
I'd love to hear a better way to do this, though. And would love even more if most of this was already written and shared to save me some time. :-)
I see this is mvc application=> your solution would lie in routing(for me_)
you know every option which is not marked as [nonaction] is registered in Global.asax which contains
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
and in this routes you will be able to find all accessible methods =>eg actions
this is created in basic mvc
Hope this will help
Here is the important part of my solution. This works well for us.
var mvcAssembly = typeof (AccountController).Assembly;
AllControllers = mvcAssembly.GetTypes().Where(type => type.IsSubclassOf(typeof (Controller))).ToList();
UnfilteredActionHandlers = new List<MethodInfo>();
foreach (var controller in AllControllers)
{
UnfilteredActionHandlers.AddRange(controller.GetMethods()
.Where(methodInfo =>
typeof (ActionResult).IsAssignableFrom(methodInfo.ReturnType)
&& !ControllerClassesToIgnore.Contains(methodInfo.ReflectedType)));
}
We have a few collections that we filter the UnfilteredActionHandlers collection by depending on how we want to use them:
internal List<MethodInfo> UnfilteredActionHandlers { get; set; }
internal List<MethodInfo> ActionHandlersExcludingFilteredReturnTypes { get; set; }
internal List<MethodInfo> ActionHandlersFilteredByAttributes { get; set; }
internal List<MethodInfo> ActionHandlersFilteredByBoth { get; set; }
internal static List<Type> ReturnTypesToIgnore { get; set; }
internal static List<Type> RequiredAttributes { get; set; }
internal static List<Type> ControllerClassesToIgnore { get; set; }
精彩评论