最近、プロジェクトを ASP.NET MVC 5 にアップグレードしましたが、まったく同じ問題が発生しました。dotPeekを使用して調査したところ、コントローラ タイプのリストを期待するパラメータとしてMapMvcAttributeRoutes
を持つ内部拡張メソッドがあることがわかりました。IEnumerable<Type>
リフレクションを使用する新しい拡張メソッドを作成し、属性ベースのルートをテストできるようにしました。
public static class RouteCollectionExtensions
{
public static void MapMvcAttributeRoutesForTesting(this RouteCollection routes)
{
var controllers = (from t in typeof(HomeController).Assembly.GetExportedTypes()
where
t != null &&
t.IsPublic &&
t.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase) &&
!t.IsAbstract &&
typeof(IController).IsAssignableFrom(t)
select t).ToList();
var mapMvcAttributeRoutesMethod = typeof(RouteCollectionAttributeRoutingExtensions)
.GetMethod(
"MapMvcAttributeRoutes",
BindingFlags.NonPublic | BindingFlags.Static,
null,
new Type[] { typeof(RouteCollection), typeof(IEnumerable<Type>) },
null);
mapMvcAttributeRoutesMethod.Invoke(null, new object[] { routes, controllers });
}
}
そして、これが私がそれを使用する方法です:
public class HomeControllerRouteTests
{
[Fact]
public void RequestTo_Root_ShouldMapTo_HomeIndex()
{
// Arrange
var routes = new RouteCollection();
// Act - registers traditional routes and the new attribute-defined routes
RouteConfig.RegisterRoutes(routes);
routes.MapMvcAttributeRoutesForTesting();
// Assert - uses MvcRouteTester to test specific routes
routes.ShouldMap("~/").To<HomeController>(x => x.Index());
}
}
ここでの問題の 1 つは、内部RouteConfig.RegisterRoutes(route)
で呼び出すことができないroutes.MapMvcAttributeRoutes()
ため、代わりにその呼び出しを Global.asax ファイルに移動したことです。
もう 1 つの懸念は、上記の方法RouteCollectionAttributeRoutingExtensions
は内部的なものであり、いつでも削除できるため、このソリューションは脆弱である可能性があることです。予防的なアプローチは、変数が null かどうかを確認し、 null のmapMvcAttributeRoutesMethod
場合は適切なエラー/例外メッセージを提供することです。
注:これは ASP.NET MVC 5.0 でのみ機能します。ASP.NET MVC 5.1 の属性ルーティングに大幅な変更があり、mapMvcAttributeRoutesMethod
メソッドは内部クラスに移動されました。