Lately, I was working on an ASP.NET MVC web application, and one of the questions that came up to me was: How do you deal with the application’s routing table when it comes to Unit Testing and Test-driven Development?

Routing is one of the areas of your application that can easily be screwed up – and these errors then have a high likelihood to go unnoticed and make it into production. And because even small to mid-size web projects will have dozens or even of hundreds of possible URLs I find it important to have a quick and reliable strategy to deal with such a scenario (covering a bulk of URLs through tests).


Such tests are mostly the same for every single route. Usually, they only vary in two aspects:

  1. The route/URL to test
  2. The target (i.e. controller and action method)

So I looked around for what’s available out of the box and I found the MvcRouteTester library. It is a great piece of work and fits the bill completely. It is available via NuGet, some usage documentation can be found here, and there are also some author’s considerations about the project.

I combined the MvcRouteTester library with my favourite unit testing framework (xUnit.Net) to implement some data-driven, tabular-style tests. And because this scenario is not so uncommon, I thought I’d share the results here, presenting a simple and easy-to-implement solution for testing ASP.NET MVC route tables (Oh, and don’t worry if you’re using a different unit testing framework, the story is largely the same for all of them…).

Should Routes Be Tested at all?

Well, exclusively seen from a pure technical viewpoint, probably not. Here’s why:

Some would perhaps argue that in certain cases, especially if you stick to RESTful approach, this type of testing wouldn’t even be necessary, because the convention over configuration provided by the framework means that you effecitvely end up testing something that’s internal working of Web API.
Filip W.: Testing routes in ASP.NET Web API

While this argument may be true in a pure technical sense, things are not so clear cut in practice. The following quote perfectly describes the problem (though directed towards ‘classical’ MVC web application routes, it is equally true for Web API routes):

Have you ever gotten your MVC application’s routes working exactly the way you want — only to add a new pattern in your Global.asax that screws everything up? This used to happen to me all the time; often without realizing it until well after the fact.
from the CodePlex home of the ‘MVC Route/URL Generation Unit Tester’ project

Usage

Supposed you subscribe to the above and you want your routes to be covered with tests, how then would you go for it? One possibility is to have integration tests which fire up the whole MVC application in a web server and issue a Http request. While this is of course possible, it’s probably not the best strategy, because it would be slow, more fragile than it needs to be, and eventually influenced by other mechanisms that might be in operation in your project (such as e.g. URL filtering).
Instead, it would be better to have unit tests. They are much faster to execute and they come earlier in the software development lifecycle – they generally are a developer’s first line of defence against all kinds of errors. And, because there are so much different possible routes, and they all have to be tested the same way, we’d like to have tabular-style, data-driven tests, where we have to write the test only once and then add new URL definitions as required.
In this section, I will shortly go into some of the basic steps involved in authoring such tests with MvcRouteTester and xUnit.Net. (The full sample solution is available here.)

Initializing the route table

As you know, ASP.NET MVC applications have a static RouteConfig class which serves to initialize the application’s routing table. After initial project creation it looks like this:

The first thing then that we need to do is to wrap this initialization into a small helper class and make the initialized routing table accessible from outside. The following class (which is called a ‘fixture’ in xUnit.Net) does exactly that:

We then ‘inject’ that fixture it into our test class by deriving it from the IClassFixture<T> interface (so it’s IClassFixture<WebRouteConfigFixture> here) and then declaring a c’tor which takes an instance of WebRouteConfigFixture as a parameter – just as you would do when using an IoC container:

This is the xUnit.Net way of providing context to a test class, effectively doing the same as NUnit does with TestFixtureSetUp/TestFixtureTearDown methods, or MSTest with ClassInitialize/ClassCleanup methods.

Testing the route table

Now that we have everything in place, we can actually write some tests.
We may have single tests:

…data-driven test methods that declare their data directly above the method via attributes:

… or, if this becomes too bulky, via separate factory methods (this also works with properties):

And what about Web API ?

With ASP.NET Web API it’s exactly the same as with normal web applications. The only difference is that the routing table to test resides in a System.Web.Http.HttpConfiguration object and gets initialized by a class called WebApiConfig. So this is the resulting fixture:

And consequently, the test class look like this (note that you always have an additional parameter for the HTTP method):

The Sample Solution

A sample solution (VS 2013) with the above code can be downloaded here from my GitHub account.
Also note that the MvcRouteTester library has quite a few things more to offer than are shown in this short sample (e.g. stuff that revolves around HTTP handlers or dealing with MVC model binding). You may want to consult the documentation for this.

Share on Pinterest
There are no images.
Share with your friends










Submit
Category:
Testing, Test Automation & TDD
Tags:
, ,