Dot-Net

在 AreaRegistration.RegisterAllAreas() 上對帶有區域的 ASP.NET MVC 2 路由進行單元測試

  • April 26, 2010

我在 ASP.NET MVC 2 中對我的路由進行單元測試。我正在使用 MSTest,我也在使用區域。

[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());
   }
}

然而,當它執行AreaRegistration.RegisterAllAreas()時,它會拋出這個異常:

System.InvalidOperationException:System.InvalidOperationException:在應用程序的預啟動初始化階段無法呼叫此方法。

所以,我認為我不能從我的類初始化程序中呼叫它。但是我什麼時候可以呼叫它?我的測試中顯然沒有Application_Start

我通過創建我的AreaRegistration類的一個實例並呼叫該RegisterArea方法來解決這個問題。

例如,給定一個名為“Catalog”的區域,其中包含以下路由:

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

這是我的測試方法:

[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"]);
}

引用自:https://stackoverflow.com/questions/2715940