flipbit


Chris Wood

I'm an independent web and iOS developer based in London

I’ve recently started to use the Microsoft ASP.NET MVC framework. Being very familiar with the Castle Monorail, I was a bit dubious to how the Microsoft framework would hold up.

One of the first tasks I had difficulty with was writing a basic unit test to see whether a user was logged in, through holding their credentials in session:

using NUnit.Framework;

[TestFixture]
public class HomeControllerTest
{
    private HomeController controller;

    [Test]
    public void TestIndexAction()
    {
        controller = new HomeController();

        // Display the homepage
        controller.Index();

        // Verify the user object hasn't been set in session
        Assert.IsNull(controller.ControllerContext.HttpContext.Session["user"]);
    }
}

When I can to run this test, it failed as the HttpContextSessionBase class hadn’t been instantiated. After googling this, several blogs had described the same issue; however I couldn’t find an answer without manually Mocking or creating Fakes. Monorail conversely, has the solution is built into the framework:

[TestFixture]
class HomeControllerTest : BaseControllerTest
{
    private HomeController controller;

    [SetUp]
    public void SetUp()
    {
        controller = new HomeController();

        PrepareController(controller);
    }

    [Test]
    public void TestIndexAction()
    {
        // Display homepage
        controller.Index();

        // Verify the user object hasn't been set in session
        Assert.IsNull(controller.Context.Session["user"]);
    }
}

After further research, I came across the MVC Contrib Project on Codeplex. Adding references to their testing assembly I was able to write the following:

using MvcContrib.TestHelper;
using NUnit.Framework;

[TestFixture]
public class HomeControllerTest
{
    private HomeController controller;
    private TestControllerBuilder builder;

    [SetUp]
    public void SetUp()
    {
        builder = new TestControllerBuilder();

        controller = new HomeController();

        builder.InitializeController(controller);
    }

    [Test]
    public void TestIndexAction()
    {
        // Display the homepage
        controller.Index();

        // Verify the user object hasn't been set in session
        Assert.IsNull(controller.ControllerContext.HttpContext.Session["user"]);
    }
}

In order to run it requires a reference to Rhino.Mocks, so I guess under the hood this is what it’s using.

It would be good if this kind of testing simplicity was baked into the framework, as in Monorail, but it seems ASP.NET MVC still has some way to go to escape the burden of the sealed ASP.NET HttpContext classes.