170

私のコントローラーアクションの1つ、Ajaxリクエストで呼び出されているアクションは、リダイレクトを実行できるようにクライアント側にURLを返します。私は使用Url.RouteUrl(..)していますが、単体テスト中にController.Urlパラメーターが事前に入力されていないため、これは失敗します。

私は多くのことを試しましたが、特にスタブを試みた(失敗した)、スタブされた(呼び出しで失敗した)を使用してUrlHelper手動でを作成しUrlHelperました。RequestContextHttpContextBaseRouteCollection.GetUrlWithApplicationPath

私はグーグルを検索しましたが、この主題については事実上何も見つかりませんでした。Url.RouteUrlコントローラーアクションで信じられないほど愚かなことをしていますか?もっと簡単な方法はありますか?

さらに悪いことに、ユニットテストで返されたURLをテストできるようにしたいと思います。実際、正しいルートにリダイレクトされていることだけを知りたいのですが、返されるのはURLではなくURLです。ルート、解決されるURLを制御したい(たとえば、スタブを使用してRouteCollection)-しかし、最初にテストに合格できれば幸いです。

4

5 に答える 5

202

同様のケースのための私のテスト(xUnit + Moq)の1つです(コントローラーでUrl.RouteUrlを使用)

お役に立てれば:

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);
于 2009-03-23T21:18:03.860 に答える
37

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);
于 2011-12-06T23:52:55.353 に答える
12

この投稿は、HttpContextBase クラスをモックする場合に役立つ場合があります。

http://www.hanselman.com/blog/ASPNETMVCSessionAtMix08TDDAndMvcMockHelpers.aspx

于 2009-04-28T20:35:28.827 に答える
2

@ 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);
于 2009-11-10T23:04:15.787 に答える
1

http://kbochevski.blogspot.com/2010/06/unit-testing-mvcnet.htmlでは、すべてのレイヤーを単体テストでカバーする方法について説明しています。コントローラーのテストには Rhino と MVC.Contrib を使用しています。Google のソース コードは非常に役立つ場合があります。

于 2010-11-27T11:37:51.963 に答える