Saturday, June 06, 2009

ASP.Net MVC: Testing Base Controller Methods

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.

1 comments:

Anonymous said...

It is very interesting for me to read that post. Thanx for it. I like such topics and anything that is connected to them. I would like to read a bit more on that blog soon.