San*_*zen 20 .net unit-testing mstest visual-studio-2010 asp.net-mvc-2
我在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());
}
}
Run Code Online (Sandbox Code Playgroud)
AreaRegistration.RegisterAllAreas()但是,当它执行时,它会抛出此异常:
System.InvalidOperationException:System.InvalidOperationException:在应用程序的启动前初始化阶段,无法调用此方法.
所以,我认为我不能从我的类初始化程序中调用它.但我什么时候可以打电话呢?我的测试显然没有Application_Start.
Jas*_*tti 28
我通过创建我的AreaRegistration类的实例并调用该RegisterArea方法来解决这个问题.
例如,给定一个名为"Catalog"的区域,并使用此路径:
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Catalog_default",
"Catalog/{controller}/{action}/{id}",
new {controller = "List", action = "Index", id = "" }
);
}
Run Code Online (Sandbox Code Playgroud)
这是我的测试方法:
[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"]);
}
Run Code Online (Sandbox Code Playgroud)
Tod*_*ier 11
我知道我在这里迟到了,但我自己也解决了这个问题.与Jason类似的解决方案(一次注册一个区域),但是和我一样,我正在使用MvcContrib.TestHelper而不是自己做嘲弄.
[TestInitialize]
public void Setup() {
RouteTable.Routes.Clear();
var areaReg = new AdminAreaRegistration();
areaReg.RegisterArea(new AreaRegistrationContext(areaReg.AreaName, RouteTable.Routes));
}
[TestMethod]
public void admin_should_map_to_home() {
"~/Admin".ShouldMapTo<HomeController>(c => c.Index());
}
Run Code Online (Sandbox Code Playgroud)
请注意,MvcContrib对Rhino Mocks有很强的依赖性.虽然我更喜欢使用Moq,但我很高兴包含Rhino dll只是为了获得这个不错的功能.
er-*_*r-v 10
那么在测试项目中没有地方可以放置AreaRegistration.RegisterAllAreas(); 为了使它工作,因为它使用System.Web.Compilation.BuildManager类来编译网站的代码,如果在ASP.NET管道之外调用它会失败.我认为这是一种bug,因为它真的让测试很难运行.
但我发明了一个2步的解决方法:)
首先,您应该修改测试项目的App.Config文件
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
</appSettings>
<connectionStrings>
</connectionStrings>
<system.web>
<compilation debug="true">
<assemblies>
<add assembly="!!!NAME_OF_YOUR_MVC_WEB_ASSEMBLY!!!"/>
</assemblies>
</compilation>
</system.web>
</configuration>
Run Code Online (Sandbox Code Playgroud)
Actualy你应该引用包含AreaRegistration下行程序的所有程序集.第二,在AreaRegistration.RegisterAllAreas()之前添加这个丑陋的代码;
typeof(BuildManager).GetProperty("PreStartInitStage", BindingFlags.NonPublic | BindingFlags.Static).SetValue(null, 2, null);
typeof(BuildManager).GetField("_topLevelFilesCompiledStarted", BindingFlags.NonPublic | BindingFlags.Instance).SetValue( typeof(BuildManager).GetField("_theBuildManager", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null), true);
Run Code Online (Sandbox Code Playgroud)
这仅适用于.Net 4.0及更高版本
| 归档时间: |
|
| 查看次数: |
5718 次 |
| 最近记录: |