Search code examples
unit-testingtestingcastle-monorail

Entire monorail action invocation in tests


BaseControllerTest.PrepareController is enough for controller properties setup, such as PropertyBag and Context

[TestClass]
public ProjectsControllerTest : BaseControllerTest
{
 [TestMethod]
 public void List()
 {
  // Setup
  var controller = new ProjectsController();
  PrepareController(controller);
  controller.List();

  // Asserts ...
  Assert.IsInstanceOfType(typeof(IEnumerable<Project>),controller.PropertyBag["Projects"]);
 }
}

But now to run the entire pipeline for integration testing, including filters declared in action attributes?

EDIT: I'm not interested in view rendering, just the controller logic along with declarative filters.

I like the idea of moving significant amount of view setup logic into action filters, and i'm not sure if i need extra level of integration tests, or is it better done with Selenium?


Solution

  • you can get a hold of the filters, and run them.

    so, assuming action is Action<YourController>, and controller is an instance of the controller under test,

    var filtersAttributes = GetFiltersFor(controller); // say by reflecting over its attributes
    var filters = filtersAttributes
        .OrderBy(attr => attr.ExecutionOrder)
        .Select(attr => new { Attribute = attr, Instance = 
            (IFilter)Container.Resolve(attr.FilterType) }); // assuming you use IoC, otherwise simply new the filter type with Activator.CreateInstance or something
    
    Action<ExecuteWhen> runFilters = when =>
    { 
        // TODO: support IFilterAttributeAware filters
        foreach (var filter in filters) 
             if ((filter.Attribute.When & when) != 0) 
                 filter.Instance.Perform(when, Context, controller, controllerContext);
    };
    
    // Perform the controller action, including the before- and after-filters
    runFilters(ExecuteWhen.BeforeAction);
    action(controller);
    runFilters(ExecuteWhen.AfterAction);
    

    Getting the view-engine to play is trickier (though possible), but I think that testing generated views along with the controller logic is involving way too many moving and incur unjustified maintenance effort