The project that I’m working on now created the need to execute some logic before every controller action in the application executed. The ASP.Net MVC Controller class has a virtual method called OnActionExecuting which will allow me to do just what I needed. The only problem is that testing this bit of logic in the base controller wasn’t straightforward, and took a little research. This is the solution I came up with:
The class under test:
public class BaseController : Controller
{
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
ViewData["SomeKey"] = "Coming to you from a base controller!!";
}
}
The test:
[TestFixture]
public class BaseControllerTests
{
[Test]
public void Before_executing_an_action_base_controller_should_populate_view_data()
{
var baseController = new BaseController();
var baseControllerAccessor = new BaseControllerAccessor(baseController);
var actionExecutingContextMock = new Mock<ActionExecutingContext>();
baseControllerAccessor.OnActionExecuting(actionExecutingContextMock.Object);
Assert.That(baseController.ViewData["SomeKey"], Is.EqualTo("Coming to you from a base controller!!"));
}
}
The BaseController OnActionExecuting method is protected, so I had to do some jury-rigging using reflection to actually put the method under test:
public class BaseControllerAccessor
{
private BaseController _baseController;
public BaseControllerAccessor(BaseController baseController)
{
_baseController = baseController;
}
public void OnActionExecuting(ActionExecutingContext context)
{
MethodInfo methodInfo = _baseController.GetType().GetMethod("OnActionExecuting",
BindingFlags.NonPublic | BindingFlags.Instance);
methodInfo.Invoke(_baseController, new object[] {context});
}
}
This was a bit of a pain, but the peaceful easy feeling I’m getting from knowing my code is backed up with an automated test makes it all worth it.
This code can be downloaded here.