Faking HTTP Context for your unit tests

While writing and testing ASP.Net MVC application, many times over I needed to simulate HTTP Request and presence of HttpContext.Current. I need this mostly when I try to test code that interacts with MVC framework, like MVC Action Filters or custom Model Binders or testing routes.

ASP.Net MVC 4 is quite good in this matter – most of the framework can be replaced by a mocked object and there is a minimum number of static calls or sealed objects. So you can do the HTTP Simulation, but usually it involves a lot of boiler-plate code and many mock-objects to be set-up.

I’m talking about this sort of code I had to write for testing of MVC filter:

public void SetUp()
    @params = new NameValueCollection();
    responseHeaders = new NameValueCollection();

    request = new Mock<HttpRequestBase>();
    request.Setup(r => r.Params).Returns(@params);

    response = new Mock<HttpResponseBase>();
    response.Setup(r => r.Headers).Returns(responseHeaders);

    session = new HttpSessionStub();

    context = new Mock<HttpContextBase>();
    context.Setup(x => x.Request).Returns(request.Object);
    context.Setup(x => x.Session).Returns(session);
    context.Setup(x => x.Response).Returns(response.Object);

    var controller = new Mock<ControllerBase>();

    var actionDescriptor = new Mock<ActionDescriptor>();
    var controllerContext = new ControllerContext(context.Object, new RouteData(), controller.Object);
    filterContext = new AuthorizationContext(controllerContext, actionDescriptor.Object);

This is plain nasty set-up. But I had to do it for properly testing of one of our filters. At least MVC did allow me to mock the low level infrastructure!

I wanted to show you another example of that boiler-plate set-up, but could not find another one. Turned out that I’ve removed all that set up from my projects and replaced it with HttpSimultator by Phil Haak

This is a simple library that allows you to do things like this:

public void Simulator_Assigns_CurrentContext()
    using (HttpSimulator simulator = new HttpSimulator())

Or like this one:

public void CanSimulateFormPost()
    using (var simulator = new HttpSimulator())
        var form = new NameValueCollection();
        form.Add("Test1", "Value1");
        form.Add("Test2", "Value2");
        simulator.SimulateRequest(new Uri("http://localhost/Test.aspx"), form);

        Assert.AreEqual("Value1", HttpContext.Current.Request.Form["Test1"]);
        Assert.AreEqual("Value2", HttpContext.Current.Request.Form["Test2"]);

By the way, these tests are all part of the library itself. You can read a bit more on Phil’s page (link above), but here I’ll give you a link to gist with the source code. This is in case the link rots or the page dies.

Also this version is modified according to our StyleCop rules, so if you use StyleCop in your project, this one is to get!