Unit testing ASP.NET MVC 2 routes with areas bails out on AreaRegistration.RegisterAllAreas()

.net, asp.net-mvc-2, mstest, unit-testing, visual-studio-2010

Solution

I solved this by creating an instance of my `AreaRegistration` class and calling the `RegisterArea` method.

For example, given an Area named "Catalog" with this route:

public override void RegisterArea(AreaRegistrationContext context)
{
  context.MapRoute(
      "Catalog_default",
      "Catalog/{controller}/{action}/{id}",
      new {controller = "List", action = "Index", id = "" }
  );
}

This is my test method:

[TestMethod]
public void TestCatalogAreaRoute()
{
  var routes = new RouteCollection();

  // Get my AreaRegistration class
  var areaRegistration = new CatalogAreaRegistration();
  Assert.AreEqual("Catalog", areaRegistration.AreaName);

  // Get an AreaRegistrationContext for my class. Give it an empty RouteCollection
  var areaRegistrationContext = new AreaRegistrationContext(areaRegistration.AreaName, routes);
  areaRegistration.RegisterArea(areaRegistrationContext);

  // Mock up an HttpContext object with my test path (using Moq)
  var context = new Mock<HttpContextBase>();
  context.Setup(c => c.Request.AppRelativeCurrentExecutionFilePath).Returns("~/Catalog");

  // Get the RouteData based on the HttpContext
  var routeData = routes.GetRouteData(context.Object);

  Assert.IsNotNull(routeData, "Should have found the route");
  Assert.AreEqual("Catalog", routeData.DataTokens["area"]);
  Assert.AreEqual("List", routeData.Values["controller"]);
  Assert.AreEqual("Index", routeData.Values["action"]);
  Assert.AreEqual("", routeData.Values["id"]);
}

Problem

I'm unit testing my routes in ASP.NET MVC 2. I'm using MSTest and I'm using areas as well. ``` [TestClass] public class RouteRegistrarTests { [ClassInitialize] public static void ClassInitialize(TestContext testContext) { RouteTable.Routes.Clear(); RouteTable.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); RouteTable.Routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" }); AreaRegistration.RegisterAllAreas(); routes.MapRoute( "default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } [TestMethod] public void RouteMaps_VerifyMappings_Match() { "~/".Route().ShouldMapTo<HomeController>(n => n.Index()); } } ``` When it executes `AreaRegistration.RegisterAllAreas()` however, it throws this exception: System.InvalidOperationException: System.InvalidOperationException: This method cannot be called during the application's pre-start initialization stage. So, I reckon I can't call it from my class initializer. But when can I call it? I obviously don't have an `Application_Start` in my test.

Original source