Unit Testing registered routes in MVC

When you have a lot of routes in a MVC application, it could be very tricky to get things right. It is always helpful to have unit testings against the registered routes. Especially when you make changes and it makes sure you will not break anything that already exists. I will show you a couple of examples how do I write unit testings for my routes.

        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                "PageRoute", // Route name
                "Page/{action}/{id}", // URL with parameters
                new { controller = "Home", id = UrlParameter.Optional } // Parameter defaults
            );

            routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
            );

            routes.MapRoute(
                "ErrorRoute", // Route name
                "{*anything}",
                new { controller = "Home", action = "Missing"} // Parameter defaults
            );

        }

In the code snippet, I have registered 3 routes. “PageRoute”, “Default” and “ErrorRoute”.

Now let’s create a unit testing project, and use Moq as the mock framework. (You can also use Rhino Mocks). Don’t forget to reference you mvc application then we are ready to write some tests.

    [TestClass]
    public class HomeControllerTest
    {
        [TestMethod]
        public void DefaultRouteTest()
        {
            var routes = new RouteCollection();
            MvcApplication.RegisterRoutes(routes);

            var context = new Mock<HttpContextBase>();
            context.Setup(p => p.Request.AppRelativeCurrentExecutionFilePath).Returns("~/");
            var routeData = routes.GetRouteData(context.Object);

            Assert.AreEqual(((Route)routeData.Route).Url, "{controller}/{action}/{id}");
            Assert.AreEqual("Home", routeData.Values["controller"], "default controller is home controller");
            Assert.AreEqual("Index", routeData.Values["action"], "default action");
        }

        [TestMethod]
        public void PageRouteTest()
        {
            var routes = new RouteCollection();
            MvcApplication.RegisterRoutes(routes);

            var context = new Mock<HttpContextBase>();
            context.Setup(p => p.Request.AppRelativeCurrentExecutionFilePath).Returns("~/Page/About");
            var routeData = routes.GetRouteData(context.Object);

            Assert.AreEqual(((Route)routeData.Route).Url, "Page/{action}/{id}");
            Assert.AreEqual("Home", routeData.Values["controller"], "default controller is home controller");
            Assert.AreEqual("About", routeData.Values["action"], "default action");
        }

        [TestMethod]
        public void ErrorRouteTest()
        {
            var routes = new RouteCollection();
            MvcApplication.RegisterRoutes(routes);

            var context = new Mock<HttpContextBase>();
            context.Setup(p => p.Request.AppRelativeCurrentExecutionFilePath).Returns("~/DDA/asd/asd/asd/WhereIsIt");
            var routeData = routes.GetRouteData(context.Object);

            Assert.AreEqual(((Route)routeData.Route).Url, "{*anything}");
            Assert.AreEqual("Home", routeData.Values["controller"], "default controller is home controller");
            Assert.AreEqual("Missing", routeData.Values["action"], "default action");

        }

    }

When writing the unit tests, you will need to mock HttpContextBase and setup the Request.AppRelativeCurrentExecutionFilePath and make it returns your targeting url. Pass the context to your route collection. You can use Assert to test what route is returned in the RouteData.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s