Test your MVC routes with Moq

Routing is a great feature that ships with MVC. The ASP.NET Routing module is responsible for mapping incoming browser requests to particular MVC controller actions. One of the great things about routing in MVC is the ability to rewrite a URL and make it a lot more readable. This is also meant to be better for SEO, but I like that fact the URL's are easy to type and easier to remember.

If you've had a look at an ASP.NET MVC application before you will notice that it handles URL's differently to your standard ASP.NET Webforms. One of the things that I worry about when playing around with the routing is messing up other routes. This is where unit testing comes in very handy.

A great way to test this would be to use a Mocking framework. I normally use Moq, but you could use any .Net based mocking framework. For this example however, we will stick to Moq. If you haven't worked with Moq before, please take a look at these two other posts that I have written on them here and here.

Lets take a look at the default route that is included in our Global.asax file.

One of the advantages of using Moq in this instance, is that it allows us to create a fake HttpContextBase and HttpRequestBase. Lets apply this and write a unit test to test this:

In the first section (Arrange), we are setting up the fake data that the HttpContextBase should return. Once that is done we tell it to return the route "~/Home/About".

We then get our RouteCollection to return the route data for that HttpContextBase that we have setup.

And finally, we are checking all the values that are returned to see if they match the Controller, the action and any Id that was passed in. Let's try this same pattern for another route that is a little more complicated. We should be able to test for similar results.

In this instance, the route is slightly different. We are also going to add a bit of complexity by adding some parameters.

Again we are mocking an HttpContext and setting it up to return the route "~/Home/Product/Jeans/2". If this were in a controller and we were passing a model to the view, we would expect the view to return a product with an id of 2 - ie a pair of jeans.

Finally, we can test that the values passed in the URL - "~/Home/Product/Jeans/2" are getting sent and the routes are getting mapped correctly.

I hope this helps with any issues you may have had with testing your routes in MVC. It might also be a good idea to run a set of tests against your routes whenever you make any changes!