Announcing NTestDataBuilder library

Further to the blog post I posted yesterday about the approach to generating test fixture data for automated tests that my team has adopted I have open sourced a base class and other supporting code infrastructure to quickly, tersely and maintainably generate fixture data in a consistent way.

I have released this library to GitHub and NuGet under the name NTestDataBuilder.

The GitHub page has a bunch of code snippets that will get you started quickly. Read my previous blog post to get a feel for how I use the code and in particular how I combine the approach with the Object Mother pattern for best effect.

Enjoy!

Test Data Generation the right way: Object Mother + Test Data Builders + NSubstitute + NBuilder

Generating test data for automated testing is an area that I have noticed can get very, very tedious when your application gets more and more complex. More importantly, it’s an area that I have noticed results in hard-to-maintain test logic. If you are a proponent of treating test code with the same importance of production code like I am, then you will want to refactor your test logic to make it more simple, maintainable and DRY.

In my last two projects I have been working with my team to come up with a good solution for this problem and I’m pretty stoked with what we’ve got so far. While I certainly had my hand in the end result, I certainly can’t claim all of the credit – far from it! Big props to my team mates Matt Kocaj and Poya Manouchehri for significant contributions to this.

Newing up objects everywhere

If you organically grow your automated test suite without thinking about how you are generating your test data then it’s likely you will end up with a lot of tests that have arrange sections full of object instantiation, and these sections are likely to get more and more complex as your object model gets complex (what if you need to have a customer that has 3 orders, each with 3 products?).

If you are diligent with refactoring your tests then you will likely start pulling out common instantiations to private methods (or similar), but even then you are likely to notice the following patterns start to emerge:

  • If you need to change the constructor of one of your classes there will be many, many instantiations using that constructor across your test project and so that refactor becomes a pain (and you are likely to do hacks like add default values that you wouldn’t otherwise when adding new parameters to make it easier).
  • There is likely to be a lot of repetition across different test classes in the objects that are created.
  • Building lists is really verbose and will likely feature a lot of repetition / hard-to-read code.
    • You can bring in libraries like NBuilder to make this easier and more readable.
    • You can’t use the best parts of NBuilder if you are not using public property setters so you can enforce domain invariants.
  • Your approach to generating data will be largely inconsistent across test classes – some will have private methods, some will do it inline, some might delegate to factories or helper classes etc. – this makes the code hard to understand and maintain.
  • It’s not immediately clear which of the parameters you are passing into the constructor are there to meet the requirements of the call and which are there because the test dictates it – this means the intent of your test is somewhat obscured

Object Mother

A good approach to start to address the problem is to implement the Object Mother pattern. This allows you to quickly and tersely create pre-canned objects and give them a descriptive name. Now instead of having complex chains of object instantiations you have one line of code (e.g. ObjectMother.CustomerWith3FilledOrders), which is a lot more descriptive and your tests become simpler as a result. This also helps ensure that your approach for data generation is consistent, and thus more maintainable.

If you just use Object Mother though, you will likely observe the following problems:

  • While your constructor calls are likely to be in one file now, there is still potentially a lot of calls so it’s still tricky to make constructor changes.
  • As soon as you have a small tweak needed for the data returned there is a tendency to simply create a new Object Mother property.
  • Because of this, the Object Mother class can quickly get unwieldy and a nightmare to maintain and understand – it becomes a god object of sorts.

Test Data Builder

An approach that seems to have stemmed from the Object Mother pattern is the application of the builder pattern to result in the Test Data Builder pattern. This involves creating a builder class responsible for creating a particular type of object via a fluent interface that keeps track of the desired state of the object being built before being asked to actually build the object.

This provides a number of advantages:

  • Your constructor calls will be in your test project once only making them easy to change.
  • You have a readable, discoverable, fluent interface to generate your objects making your tests easy to read/write/maintain.
  • You are consistent in how you generate your test data.
  • It works with objects that you don’t have public property setters for since there is an explicit build action, which can invoke the constructor with the parameters you have set.
  • It’s flexible enough to give you the ability to express and perform actions to your object after it’s constructed – e.g. specify that an order is paid (which might be a Pay() method rather than a constructor parameter; you wouldn’t expect to be able to create an order in the paid state!).
  • Because of this your builder objects provide a blueprint / documentation for how to interact with your domain objects.
  • The test data builder can contain sensible defaults for your object instantiation and thus your test only needs to specify the values that need to be arranged thus making the intent of your test very clear
  • We have added a method to our builders (.AsProxy()) that allows the object returned to be an NSubstitute substitute (a proxy / mock object if you aren’t familiar with that library) rather than a real object (with the public properties set to automatically return the values specified in the builder). See below for a code snippet.
    • This means that when we need substitutes to check whether certain methods are called or to ensure that certain method calls return predetermined values we can generate those substitutes consistently with how we generate the real objects.
    • This is very powerful and improves understandability and maintainability of the tests.
    • In general we try and avoid using substitutes because it means that it’s possible to get objects that violate domain invariants, however, on occasion it’s very useful to properly unit test a domain action when it interacts with other domain objects

Here is a (somewhat contrived) example of the .AsProxy() method described above.

public void Given10YearMembership_WhenCalculatingDiscount_ThenApply15PercentLongMembershipDiscount() {
    var member = MemberBuilder.AsProxy().Build();
    member.GetYearsOfMembership(Arg.Any()).Returns(10);

    var discount = _discountCalculator.CalculateDiscountFor(member, new DateTimeProvider());

    Assert.That(discount, Is.EqualTo(0.15));
}

Combining NBuilder and the Test Data Builders

Another cool thing we have done is to combine our test data builders with NBuilder to allow for terse, expressive generation of lists of objects while still supporting objects that don’t have public property setters. We do this by generating a list of builders with NBuilder and then iterating that list to build each builder and get the actual object. Here is an example:

var members = Builder.CreateListOfSize(4)
    .TheFirst(1).With(b => b.WithFirstName("Rob"))
    .TheNext(2).With(b => b.WithFirstName("Poya"))
    .TheNext(1).With(b => b.WithFirstName("Matt"))
    .Build()
    .Select(b => b.Build());

We have made the above code even terser, by adding some extension methods to allow for this:

var members = MemberBuilder.CreateList(4)
    .TheFirst(1).With(b => b.WithFirstName("Rob"))
    .TheNext(2).With(b => b.WithFirstName("Poya"))
    .TheNext(1).With(b => b.WithFirstName("Matt"))
    .BuildList();

Adding back Object Mother

One of the really nice things about the Object Mother pattern is that you reduce a lot of repetition on your tests by re-using pre-canned objects. It also means the tests are a lot terser since you just specify the name of the pre-canned object that you want and assuming that name describes the pre-canned object well then your test is very readable.

What we have done is combined the maintainability and flexibility that is afforded by the Test Data Builder pattern with the terseness afforded by the Object Mother by using Object Mothers that return Test Data Builders. This overcomes all of the disadvantages noted above with the Object Mother pattern.

In order to make it easy to find objects we also use a static partial class for the Object Mother – this is one of the few really nice uses I’ve seen for partial classes. Basically, we have an ObjectMother folder / namespace in our test project that contains a file for every entity we are generating that includes a static nested class within the root ObjectMother class. This ensures that all test data is gotten by first typing “ObjectMother.” – this makes it really consistent and easily accessible, while not having an unmaintainable mess of a god object.

For instance we might have (simple example):

// Helpers\ObjectMother\Customers.cs
using MyProject.Tests.Helpers.Builders;

namespace MyProject.Tests.Helpers.ObjectMother
{
    public static partial class ObjectMother
    {
        public static class Customers
        {
            public static CustomerBuilder Robert
            {
                get { return new CustomerBuilder().WithFirstName("Robert"); }
            }
            public static CustomerBuilder Matt
            {
                get { return new CustomerBuilder().WithFirstName("Matt"); }
            }
        }
    }
}

If our test requires any small tweaks to the predefined object then you don’t need to necessarily add another property to your object mother – you can use the methods on the builder, e.g. ObjectMother.Customers.Robert.WithLastName("Moore").Build();

We generally stick to using properties rather than methods in the object mothers since the builders mean that it’s not necessary to pass any parameters to get your pre-canned object out, but occasionally we do have some that have methods when there is something meaningful to configure that makes sense in the object mother e.g. ObjectMother.Members.MemberWithXProducts(int numProducts).

Making the Test Data Builders terse

One argument against this approach, particularly when you first start out your test project (or indeed if you decide to refactor it to use this technique after the fact) is that you are writing a lot of code to get it all up and running. We decided to avoid that by using a number of techniques:

  • We set any reasonable defaults in our builder constructor so new CustomerBuilder().Build() will give a reasonable object (unless for that particular type of object there are any properties that make sense to always have to specify, in which case we don’t add a default for that property).
  • We have created a base class that allows us to set/get the property values into a dictionary using a lambda expression that identifies the property whose value is being set/retrieved – this reduces the code in the builder by eliminating the need for most (sometimes there is still a need to keep state in the builder where you are storing something not expressed by one of the properties) of the private variables in the builder.
  • We only add fluent methods for the properties we are actually using in our tests that point in time – this means we don’t have dead methods lying around in the builders and initially they are very terse.
  • We have a base class that defines a lot of the common infrastructure behind defining a builder (including the ability to return a proxy object and the ability to create a list of builders using NBuilder – I’ve open sourced the code as NTestDataBuilder).

This generally means that we can be up and running with an object mother and builder for a new entity within a minute and it’s well worth doing it from the start with all our objects to keep consistency in the codebase and ensure all tests are maintainable, terse and readable from the start.

Here is an example of what I mean from the NTestDataBuilder library I have released:

class CustomerBuilder : TestDataBuilder<Customer, CustomerBuilder>
{
    public CustomerBuilder()
    {
        WithFirstName("Rob");
        WithLastName("Moore");
        WhoJoinedIn(2013);
    }

    public CustomerBuilder WithFirstName(string firstName)
    {
        Set(x => x.FirstName, firstName);
        return this;
    }

    public CustomerBuilder WithLastName(string lastName)
    {
        Set(x => x.LastName, lastName);
        return this;
    }

    public CustomerBuilder WhoJoinedIn(int yearJoined)
    {
        Set(x => x.YearJoined, yearJoined);
        return this;
    }

    protected override Customer BuildObject()
    {
        return new Customer(
            Get(x => x.FirstName),
            Get(x => x.LastName),
            Get(x => x.YearJoined)
        );
    }
}

Automated Testing of ASP.NET Web API and MVC applications

Yesterday I started working on my first professional usage of ASP.NET Web API and as part of that created a handy base class to perform full-stack unit and/or integration testing of controller actions in-process. It was based on some stuff I found online, but put my own flair on so I thought I would share it here in case anyone else found it useful. While I’m at it I thought I’d briefly outline my testing strategy for most MVC applications I write.

ASP.NET MVC Testing

When I’m testing an ASP.NET MVC application I have had good mileage with covering the following (this is a combination of what you might consider to be integration and unit tests):

  • Routes: Typically you aren’t going to change the URLs in your application (because then you would be dealing with potential search engine optimisation and bookmarking issues) so if they do change it’s a good indication that (in an MVC application) you’ve added a new route definition that has broken some existing definitions. I will typically test the URLs for all controller actions (including mapping route values to action input parameters) and test that calling Url.Route with the same parameters results in the same route being generated. This kind of testing has saved my bacon many times in the past and it is quick and effective to write the tests whenever adding a new controller action using the code I use (a version of MVCContrib.TestHelper that I modified to use NSubstitute). It’s particularly handy when you have areas in your application because they have a nasty tendency of breaking your routes.
  • Controllers: If any particular controller action is more than a few lines of code (and thus it isn’t bleedingly obviously that it’s either correct or not correct just by looking at it), then like all complex business logic I try and unit test the controllers. I do this using the Fluent MVC Testing library that I created because it’s terse and easy to write these tests.
  • Controller Instantiation: As previously blogged.
  • Filters, Filter Providers and Model Binders: I will typically unit test these, for an example see my previous post about unit testing filter providers.
  • UI Testing: If the circumstances of the project allow for it then well-placed full-stack tests provide a lot of extra confidence. My fellow TestStacker Mehdi Khalili has a brilliant slide deck on this.
  • Database Layer: I perform tests against individual queries / commands / repository methods by doing a full integration test against a real database and wrapping the whole thing in a Transaction Scope so I can roll-back any changes in the test teardown. This ensures the test database always remains clean (read: empty) and each test can work in isolation.
  • Database migrations: I like to include one test that brings the test database to version 0 and then back up to the latest version so that if you ever need to use your down migrations then you have confidence they work (as well as continuing confidence that all of your up migrations work).
  • Business logic / services / domain logic: I will always unit test this
  • Infrastructure code: Where practical I try and unit test this. Sometimes this code is tested as a result of other tests e.g. the database tests and controller instantiation tests

If there are any particular types of testing that you would like me to do a more detailed blog post feel free to add a comment below.

ASP.NET Web API

The tests above have a nice mixture of unit and integrations tests and I find that they combine to provide a good level of confidence and coverage as the codebase evolves. I have only really played around with Web API in my spare time so far so the following recommendations are likely to evolve over time, but this is my current gut feel about this kind of testing.

Firstly, there are a few good posts I came across that give a broad idea of the different ways in which you can test Web API:

And then my initial approach / thoughts:

  • Routes:The other day I stumbled across a library someone had created to do route testing for ASP.NET Web API and while I’m not a fan of the syntax they created (vs MVCContrib.TestHelper style syntax) it’s a good start in this direction. For the moment I’m thinking (as you will see) that I can take care of route testing implicitly. Furthermore, at least for my current project, the number of routes I’m dealing with doesn’t necessitate route testing. If the routes that you deal with are complex enough and or large enough in number then unit testing routes will likely provide a lot of value.
    Controllers: There is less need for a library like Fluent MVC Testing with Web API since most of your controllers will simply return the data that they queried directly and rely on formatters to give the correct response. This makes unit testing the controllers really simple. As for route testing the initial approach I’ve settled on will cover this testing anyway.
  • Controller Instantiation: For the same reason this is valuable for ASP.NET MVC projects I think this is valuable (and just as easy to test). In my current project I haven’t bothered creating this yet since I’m only dealing with one controller with a couple of dependencies so I don’t have any code for this.
  • Filters, etc.: I think there is value in unit testing these things in the same way as there is for MVC applications. In this instance the approach I’ve settled on tests these as well because it’s a full stack test. This is fine for simple filters / formatters etc., but if you have complex ones then I highly recommend unit testing them as well.
  • UI Testing: This one is interesting, because at first thought there is no UI to test so this isn’t applicable. However, the way I see it, the equivalent in API tests are testing from the viewpoint of the client/consumer e.g. if I make a get request to this URL then I expect that object in JSON format. If you are producing an API according to a specification then this is the viewpoint the specification is written in and depending on how you do things, the acceptance criteria for the work you are doing will also be in terms of this. For these reasons, I think in some ways, while it is integration testing, testing the full stack from the viewpoint of a client provides a lot of bang for buck. As I will explain further below, this is the approach I have decided to initially take. I should note that the traditional pain points of UI testing for MVC applications (cross-browser differences, really slow, out of process so you can’t easily mock things, etc.) can easily be mitigated when doing this testing, which is why I find it a suitable approach in lieu of some of the other testing I might normally do.
  • Database / business logic / infrastructure: None of this changes.

The approach I’ve taken for Web API testing

This is heavily based on the ASP.Net Web Api Integration Tests With Self Hosting post I linked to above. The problems I had with the code shown in that post was:

  • The route was defined in the test rather than re-using the routes you define in your application
  • The test itself is defined within a lamdba
  • There was no abstraction of the code to set up the server
  • The base URL was specified multiple times
  • The test was really verbose (apart from not abstracting out the server it had a stream reader and WebRequest.Create etc.)

In the end I created a base class (using NUnit, but the same applies to any unit testing framework) that abstracted away the creation of the server as well as the HTTP call. This resulted in tests that were dead simple and very terse (for the moment there is only a get request, but you can easily add other methods and headers etc.). I also exposed the dependency injection so that I could insert mocks to control whether I want to unit test the controller action or integration test it with real dependencies. In this case it uses Autofac, but again the same applies for any DI framework.

Another thing to note is that I’ve baked in support for detecting if Fiddler is currently running and proxying requests through Fiddler in that instance. That way you can seemlessly move your test between your local computer (with or without Fiddler running) and your CI server without changing any code. The fact it proxies through Fiddler makes it really easy to debug exactly what is going on too.

Two other things to note are that you need to change PingController to a controller (or any class really) in the assembly that contains your API controllers and that this assumes you have created a static method inside the RouteConfig class called RegisterApiRoutes that defines the routes for your API.

using System;
using System.Net.Http;
using System.Web.Http.SelfHost;
using Autofac;
using Autofac.Integration.WebApi;
using NUnit.Framework;
using WebApiTesting.App_Start;
using WebApiTesting.Controllers;

namespace WebApiTesting.Tests.TestHelpers
{
    class WebApiTestBase
    {
        private HttpSelfHostServer _webServer;
        protected IContainer Container { get; private set; }
        protected ContainerBuilder ContainerBuilder { get; set; }
        protected Uri BaseUri { get; private set; }

        private bool _fiddlerActive = true;

        [TestFixtureSetUp]
        public void TestFixtureSetup()
        {
            var client = new HttpClient();
            try
            {
                client.GetAsync("http://ipv4.fiddler/").Wait();
            }
            catch (Exception)
            {
                _fiddlerActive = false;
            }
        }

        [SetUp]
        public virtual void Setup()
        {
            BaseUri = new Uri("http://localhost:3000");
            var config = new HttpSelfHostConfiguration(BaseUri);

            ContainerBuilder = ContainerBuilder ?? new ContainerBuilder();
            ContainerBuilder.RegisterApiControllers(typeof(PingController).Assembly);
            Container = ContainerBuilder.Build();

            RouteConfig.RegisterApiRoutes(config);
            config.DependencyResolver = new AutofacWebApiDependencyResolver(Container);

            _webServer = new HttpSelfHostServer(config);
            _webServer.OpenAsync().Wait();
        }

        protected HttpResponse PerformGetTo(string url)
        {
            var client = new HttpClient();
            var response = client.GetAsync((_fiddlerActive ? "http://ipv4.fiddler:3000/" : BaseUri.ToString()) + url).Result;
            var content = response.Content.ReadAsStringAsync().Result;

            return new HttpResponse { Content = content, Response = response };
        }

        [TearDown]
        public void Teardown()
        {
            _webServer.CloseAsync().Wait();
            _webServer.Dispose();
            Container.Dispose();
            ContainerBuilder = null;
            Container = null;
        }
    }

    class HttpResponse
    {
        public string Content { get; set; }
        public HttpResponseMessage Response { get; set; }
    }
}

So, how exactly do you use this class? Great question, but first a bit of context. My example will be for a endpoint at /api/ping that takes a GET request and returns the UTC system time in ISO format within an object with a property “Timestamp” along with a 200 OK if the database is up and running or a blank response with a 500 error if the database is not up and running.

Here is my test class:

using System;
using System.Net;
using Autofac;
using NSubstitute;
using NUnit.Framework;
using WebApiTesting.Infrastructure;
using WebApiTesting.Tests.TestHelpers;

namespace WebApiTesting.Tests.Controllers
{
    internal class PingControllerTests : WebApiTestBase
    {
        private IDateTimeProvider _dateTimeProvider;
        private IPingRepository _pingRepository;

        [SetUp]
        public override void Setup()
        {
            ContainerBuilder = new ContainerBuilder();
            _dateTimeProvider = Substitute.For<IDateTimeProvider>();
            _pingRepository = Substitute.For<IPingRepository>();
            ContainerBuilder.Register(c => _dateTimeProvider);
            ContainerBuilder.Register(c => _pingRepository);
            base.Setup();
        }

        [Test]
        public void GivenTheDatabaseIsUpAndRunning_WhenGetToPing_ReturnCurrentTimestampAnd200Ok()
        {
            _dateTimeProvider.Now().Returns(new DateTimeOffset(new DateTime(2012, 11, 4, 12, 20, 6), TimeSpan.Zero));

            var response = PerformGetTo("api/ping");

            Assert.That(response.Response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
            Assert.That(response.Content, Is.EqualTo(@"{""Timestamp"":""2012-11-04 12:20:06""}"));
        }

        [Test]
        public void GivenTheDatabaseIsNotRunning_WhenGetToPing_Return500ErrorWithNoContent()
        {
            _pingRepository.When(r => r.CheckDatabase()).Do(a => { throw new Exception(); });

            var response = PerformGetTo("api/ping");

            Assert.That(response.Response.StatusCode, Is.EqualTo(HttpStatusCode.InternalServerError));
            Assert.That(response.Content, Is.EqualTo(string.Empty));
        }
    }
}

There are a few things to note:

  • To register the listener to the port you need to run Visual Studio (and your CI test runner) as admin otherwise you will get a could not register port error.
  • I used port 3000, but if you are running as admin and get an error saying that port can’t be registered it then you might have something else on that port so feel free to change.
  • Unfortunately I couldn’t make use of AutoSubstitute, but unfortunately that broke the HTTP server (I imagine because it was giving mocks for things that the server needed real stuff for). The downside of this is that I have to keep track of the dependencies of the controller within the test making the test more verbose.
  • Because I need the container builder before starting up the web server I have to create the container builder in the setup method and register everything that I need to mock for any of the tests there, rather than setting up what needs to be mocked in each individual test.
  • I am setting up and shutting down the web server for each test to isolate them, but if there are a lot of tests this might be too slow and attaching start up to fixture setup or even test assembly set up might be a better option.
  • As mentioned above for now there is only a PerformGetTo method, but it would be easy to support the other things needed.

I’ve uploaded the example source code to Github. Feel free to fork it and play around. If you have any suggestions or improvements feel free to add a comment 🙂

Enjoy!

Explaining seemingly weird NSubstitute behaviour

I think that NSubstitute is an absolutely amazing library! I’ve used a few different mocking libraries and NSubstitute is hands down the best one. Not only is the syntax beautiful and terse, but it’s the simplest mocking library you could ever use. Don’t know the difference between a mock and a stub? WHO CARES! It’s not something you should need to know. I couldn’t explain it better than the NSubstitute homepage:

Mock, stub, fake, spy, test double? Strict or loose? Nah, just substitute for the type you need!

NSubstitute is designed for Arrange-Act-Assert (AAA) testing, so you just need to arrange how it should work, then assert it received the calls you expected once you’re done. Because you’ve got more important code to write than whether you need a mock or a stub.

99 times out of 100 you will have nothing but pleasure with NSubstitute, but like all things it’s not perfect. When I first started using NSubstitute I didn’t realise how it was implemented and just assumed it used some sort of crazy voodoo magic. More recently, I’ve actually contributed to NSubstitute to fix a bug I was experiencing. After doing so, I understand a lot more now how it actually works. It turns out it’s not magic, but it is very clever.

One of the things that can trip you up about the way it’s implemented is due to the fact that .Returns and Arg.Any/Is are based on a static stack and thus sometimes if you do things like set up a received check or return value for a  non-virtual method or set up a return value using the result of a substituted call then what the code looks like it should do doesn’t actually happen. When this does happen, if you don’t understand the implementation of what’s going on then this can be incredibly difficult to diagnose and you will generally spend a few confused hours.

This recently happened for some of the devs on my team and I wanted to try and explain to them what was happening so I came up with a gist that shows some examples for .Returns of the effect the static stack implementation has. I haven’t done any for Arg.Is/Any at this stage.

If you come across problems with NSubstitute or you need to explain to other people this behaviour feel free to use my gist. It uses NUnit and all of the tests in the gist passed when I ran it (against NSubstitute 1.4.3).

AutofacContrib.NSubstitute v3 release

I’d like to announce a new release for the AutofacContrib.NSubstitute library. The library was in need of a bit of love because it forced you to use a really old NSubstitute version.

I’ve made the following changes:

  • Deprecated the AutoMock class in favour of AutoSubstitute (in keeping with the theme of the NSubstitute library).
  • Added a new constructor that allows you to make modifications to the ContainerBuilder before the IContainer is built.
  • Dependency on the latest version of NSubstitute and removed the hard restriction on the NSubstitute and Autofac version numbers so the package is compatible with the latest versions of those libraries.
  • Moved the source to Github
  • Added some documentation and an example class showing some usage examples

Enjoy!

Testing Url Helper within controllers in ASP.NET MVC

I recently had some code like the following in a controller that I wanted to test. The Facebook Connect API, despite being fairly awesome, is tied to the URL of the page so whenever you change the URL of your page then you will lose all your comments. This code was to get the initial URL of the page and store it in the database so that URL was used from then on:

var url = ControllerContext.RequestContext.HttpContext.Request.Url;
vm.FacebookCommentUrl = string.Format("https://{0}{1}", url.Authority, Url.Action("Detail", new { Id = "000", Controller = ArticleType.ToString() })).Replace("000", "{0}");

It’s easy to mock Request.Url within the ControllerContext; something like MVCContrib.TestHelper will mock it out for you with a few lines of code. Personally, I use the following code in conjunction with the AutoMock library to do it:

    public static class AutoMockContainer
    {
        public static AutoMock Create()
        {
            var autoMock = new AutoMock();

            var httpContext = Substitute.For<HttpContextBase>();
            autoMock.Provide(httpContext);

            var server = Substitute.For<HttpServerUtilityBase>();
            httpContext.Server.Returns(server);

            var request = Substitute.For<HttpRequestBase>();
            var parameters = new NameValueCollection();
            request.Params.Returns(parameters);
            var formParameters = new NameValueCollection();
            request.Form.Returns(formParameters);
            var qsParameters = new NameValueCollection();
            request.QueryString.Returns(qsParameters);
            var headers = new NameValueCollection();
            headers.Add("Host", "localhost");
            request.Headers.Returns(headers);
            request.AppRelativeCurrentExecutionFilePath.Returns("~/");
            request.ApplicationPath.Returns("/");
            request.Url.Returns(new Uri("http://localhost/"));
            request.Cookies.Returns(new HttpCookieCollection());
            request.ServerVariables.Returns(new NameValueCollection());
            autoMock.Provide(request);
            httpContext.Request.Returns(request);

            var response = Substitute.For<HttpResponseBase>();
            response.Cookies.Returns(new HttpCookieCollection());
            response.ApplyAppPathModifier(Arg.Any<string>()).Returns(a => a.Arg<string>());
            autoMock.Provide(response);
            httpContext.Response.Returns(response);

            var routeData = new RouteData();

            var requestContext = Substitute.For<RequestContext>();
            requestContext.RouteData = routeData;
            requestContext.HttpContext = httpContext;
            autoMock.Provide(requestContext);

            var actionExecutingContext = Substitute.For<ActionExecutingContext>();
            actionExecutingContext.HttpContext.Returns(httpContext);
            actionExecutingContext.RouteData.Returns(routeData);
            actionExecutingContext.RequestContext = requestContext;
            autoMock.Provide(actionExecutingContext);

            var actionExecutedContext = Substitute.For<ActionExecutedContext>();
            actionExecutedContext.HttpContext.Returns(httpContext);
            actionExecutedContext.RouteData.Returns(routeData);
            actionExecutedContext.RequestContext = requestContext;
            autoMock.Provide(actionExecutedContext);

            var controller = Substitute.For<ControllerBase>();
            autoMock.Provide(controller);
            actionExecutingContext.Controller.Returns(controller);

            var controllerContext = Substitute.For<ControllerContext>();
            controllerContext.HttpContext = httpContext;
            controllerContext.RouteData = routeData;
            controllerContext.RequestContext = requestContext;
            controllerContext.Controller = controller;
            autoMock.Provide(controllerContext);
            controller.ControllerContext = controllerContext;

            var iView = Substitute.For<IView>();
            autoMock.Provide(iView);

            var viewDataDictionary = new ViewDataDictionary();
            autoMock.Provide(viewDataDictionary);

            var iViewDataContainer = Substitute.For<IViewDataContainer>();
            iViewDataContainer.ViewData.Returns(viewDataDictionary);
            autoMock.Provide(iViewDataContainer);

            var textWriter = Substitute.For<TextWriter>();
            autoMock.Provide(textWriter);

            var viewContext = new ViewContext(controllerContext, iView, viewDataDictionary, new TempDataDictionary(), textWriter)
            {
                HttpContext = httpContext,
                RouteData = routeData,
                RequestContext = requestContext,
                Controller = controller
            };
            autoMock.Provide(viewContext);

            return autoMock;
        }

        public static T GetController<T>(this AutoMock autoMock) where T : Controller
        {
            var routes = new RouteCollection();
            MyApplication.RegisterRoutes(routes);
            var controller = autoMock.Resolve<T>();
            controller.ControllerContext = autoMock.Resolve<ControllerContext>();
            controller.Url = new UrlHelper(autoMock.Resolve<RequestContext>(), routes);
            return controller;
        }
    }

Above is the current version of the code that I use, but I change it every now and then when there is some other part of MVC that I need to mock, but haven’t yet. In this particular instance I was having trouble figuring out how to get Url.Action to return the actual URL – it was returning an empty string. I was registering my routes by calling the static method in my MvcApplication class, but that wasn’t enough. It took some Googling and perseverance to finally find the right set of steps to get it working (the one that really threw me was having to mock ApplyAppPathModifier in the Response object!):

  1. Register your routes in the route table
  2. Mock Request.Url (new Uri(“http://someurl/”))
  3. Mock Request.AppRelativeCurrentExecutionFilePath (“~/”)
  4. Mock Request.ApplicationPath (“/”)
  5. Mock Request.ServerVariables (new NameValueCollection())
  6. Mock Response.ApplyAppPathModifier(…) (return what is passed into it!)
  7. Set the UrlHelper in your controller to: new UrlHelper(A mock for request context with the above mocked, A route collection which has your applications routes registered into it);

Quite a strange an bizarre set of steps, but it’s what’s required to get around the core implementation within ASP.NET MVC. Maybe they will make it easier to test in the future…

With the above code snippet, I can do the following two lines of code to automatically get a controller with everything mocked correctly (not to mention any interfaces in it’s constructor automatically set to an NSubstitute Mock!):

var autoMock = AutoMockContainer.Create();
var controller = autoMock.GetController<HomeController>();