私のコントローラーアクションの1つ、Ajaxリクエストで呼び出されるアクションは、リダイレクトを実行できるようにクライアント側にURLを返すことです。 Url.RouteUrl(..)
を使用していますが、Controller.Url
パラメーターが事前入力されていないため、ユニットテスト中にこれが失敗します。
UrlHelper
をスタブしようとして(失敗しました)、スタブUrlHelper
を持つRequestContext
を使用してHttpContextBase
を手動で作成しようと試みました。 (RouteCollection.GetUrlWithApplicationPath
呼び出しで失敗しました)。
Googleで検索しましたが、この件については事実上何も見つかりませんでした。 ControllerアクションでUrl.RouteUrl
を使用して非常に愚かなことをしていますか?もっと簡単な方法はありますか?
さらに悪いことに、ユニットテストで返されたURLをテストできるようにしたいです。実際、正しいルートにリダイレクトしていることを知りたいだけですが、ルート、解決されたURLを制御したいと思います(例えば、スタブRouteCollection
を使用して)-しかし、私は最初からテストに合格して喜んでいるでしょう。
同様のケース(コントローラーでUrl.RouteUrlを使用)のための私のテスト(xUnit + Moq)の1つを次に示します。
お役に立てれば:
var routes = new RouteCollection();
MvcApplication.RegisterRoutes(routes);
var request = new Mock<HttpRequestBase>(MockBehavior.Strict);
request.SetupGet(x => x.ApplicationPath).Returns("/");
request.SetupGet(x => x.Url).Returns(new Uri("http://localhost/a", UriKind.Absolute));
request.SetupGet(x => x.ServerVariables).Returns(new System.Collections.Specialized.NameValueCollection());
var response = new Mock<HttpResponseBase>(MockBehavior.Strict);
response.Setup(x => x.ApplyAppPathModifier("/post1")).Returns("http://localhost/post1");
var context = new Mock<HttpContextBase>(MockBehavior.Strict);
context.SetupGet(x => x.Request).Returns(request.Object);
context.SetupGet(x => x.Response).Returns(response.Object);
var controller = new LinkbackController(dbF.Object);
controller.ControllerContext = new ControllerContext(context.Object, new RouteData(), controller);
controller.Url = new UrlHelper(new RequestContext(context.Object, new RouteData()), routes);
Eu-ge-neからの修正された実装。これは、アプリケーションで定義されたルートに基づいて生成されたリンクを返します。 eu-ge-neの例は常に固定応答を返しました。以下のアプローチにより、正しいアクション/コントローラーおよびルート情報がUrlHelperに渡されることをテストできます。これは、UrlHelperの呼び出しをテストする場合に必要なものです。
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.Setup(ctx => ctx.Request).Returns(request.Object);
context.Setup(ctx => ctx.Response).Returns(response.Object);
context.Setup(ctx => ctx.Session).Returns(session.Object);
context.Setup(ctx => ctx.Server).Returns(server.Object);
request.SetupGet(x => x.ApplicationPath).Returns("/");
request.SetupGet(x => x.Url).Returns(new Uri("http://localhost/a", UriKind.Absolute));
request.SetupGet(x => x.ServerVariables).Returns(new NameValueCollection());
response.Setup(x => x.ApplyAppPathModifier(It.IsAny<string>())).Returns<string>(x => x);
context.SetupGet(x => x.Request).Returns(request.Object);
context.SetupGet(x => x.Response).Returns(response.Object);
var routes = new RouteCollection();
MvcApplication.RegisterRoutes(routes);
var helper = new UrlHelper(new RequestContext(context.Object, new RouteData()), routes);
この投稿は、HttpContextBaseクラスをモックする場合に役立ちます。
http://www.hanselman.com/blog/ASPNETMVCSessionAtMix08TDDAndMvcMockHelpers.aspx
@ eu-ge-neによる答えを作り上げてくれて、とても助かりました。
リダイレクトを実行するActionResultと、FormCollectionパラメーターを指定したUpdateModel呼び出しがありました。 UpdateModel()が機能するためには、これをモックされたHttpRequestBaseに追加する必要がありました。
FormCollection collection = new FormCollection();
collection["KeyName"] = "KeyValue";
request.Setup(x => x.Form).Returns(collection);
request.Setup(x => x.QueryString).Returns(new NameValueCollection());
リダイレクトされたURLが正しいことをテストするには、次を実行できます。
RedirectResult result = controller.ActionName(modelToSubmit, collection) as RedirectResult;
Assert.AreEqual("/Expected/URL", result.Url);
http://kbochevski.blogspot.com/2010/06/unit-testing-mvcnet.html すべてのレイヤーを単体テストでカバーする方法について説明します。コントローラーのテストにはRhinoとMVC.Contribを使用します。グーグルのソースコードは大きな助けになるかもしれません。