5

目標: 特定の URL が特定のコントローラー関数を返すことをテストします。

その過程で、ルーティング システムに侵入してしまい、ルートをテストする方法がわかりません (さらに言えば、ルートに対応するコントローラーを見つけることもできません :-/)。

動作しないサンプルコード:

[Test]       
public void kick_the_tires()
{
   var rc = new RouteCollection();

   Infrastructure.RouteRegistry.RegisterRoutes(rc);

   // get the route corresponding to name.
   var got = rc["name"];

   var expected = //What? foo is an internal type that can't be instantiated.

   Assert.AreEqual(foo, frob);
}

編集: スタブ クラスの Simon からのリンクされたブログ投稿を使用します。

[TestCase("/", "~/", "Home", "Index")]
[TestCase("/", "api/command", "Other", "command")]
internal void stub_mocker(string apppath, string route, string expected_controller,\
  string expected_action)
{
  var rc = new RouteCollection();
  Infrastructure.RouteRegistry.RegisterRoutes(rc);

  var httpmock = new StubHttpContextForRouting(
      appPath: apppath,
      requestUrl: route);

  // this always returns null for everything but the Index case.
  var routeData = rc.GetRouteData(httpmock);

  var controller = routeData.Values["controller"];
  var action = routeData.Values["action"];
  Assert.AreEqual(expected_controller, controller);
  Assert.AreEqual(expected_action, action);
}
4

2 に答える 2

5

現在テストしているのは、ルート名でアクセスしてルートがコレクションに追加されているかどうかだけであり、仮想パスを指定して予想されるルートが返されるかどうかではありません。HttpContext を使用して RouteCollection によって返されるルート データを取得する必要があります。

最善の方法は、HttpContext (または HttpContextBase) のモックまたはスタブを使用し、RouteCollection の GetRouteData(HttpContextBase) メソッドを呼び出してルート データを検査することです。

Brad Wilson のブログに、この良い例があります。

編集: RouteData 自体からコントローラー インスタンスを取得することはできません。ただし、RouteData は、どのコントローラーがインスタンス化されるかを知るのに十分な情報を提供する必要があります。たとえばMyProject.Controllers.HomeController、 action を持つコントローラーがある場合Home、これはテストでも当てはまります (xUnit と Moq を使用):

// Prepare
var context = new Mock<HttpContextBase>();
var request = new Mock<HttpRequestBase>();
var response = new Mock<HttpResponseBase>();
var session = new Mock<HttpSessionStateBase>();
var server = new Mock<HttpServerUtilityBase>();

context.SetupGet(c => c.Request).Returns(request.Object);
context.SetupGet(c => c.Response).Returns(response.Object);
context.SetupGet(c => c.Session).Returns(session.Object);
context.SetupGet(c => c.Server).Returns(server.Object);
request.SetupGet(r => r.HttpMethod).Returns("GET");
request.SetupGet(r => r.PathInfo).Returns(String.Empty);
request.SetupGet(r => r.AppRelativeCurrentExecutionFilePath).Returns("~/Home");


var expectedHandler = typeof (HomeController).GetMethod("Index", Type.EmptyTypes);

var data = RouteTable.Routes.GetRouteData(context.Object);

Assert.NotNull(data);

var handler = (MethodInfo) data.DataTokens["actionMethod"];
Assert.Equal(expectedHandler, handler);
于 2013-06-25T00:37:37.050 に答える