ASP.NET MVC:使用UrlHelper的unit testing控制器
我的控制器操作之一,即在Ajax请求中调用的一个操作,正在向客户端返回一个URL,以便它可以执行redirect。 我正在使用Url.RouteUrl(..)
并在我的unit testing过程中失败,因为Controller.Url
参数未预先填充。
我尝试了很多东西,其中包括尝试存根UrlHelper
(失败),手动创buildUrlHelper
与具有存根的HttpContextBase
(在RouteCollection.GetUrlWithApplicationPath
调用失败)的RouteCollection.GetUrlWithApplicationPath
。
我search了Google,但在这个主题上几乎找不到任何东西。 我在我的控制器操作中使用Url.RouteUrl
来做一些令人难以置信的蠢事? 有更容易的方法吗?
更糟的是,我希望能够在我的unit testing中testing返回的URL – 事实上,我只是有兴趣知道它正在redirect到正确的路线,但因为我返回一个URL而不是路线,我想控制解决的URL(例如通过使用一个存根的RouteCollection
) – 但我很乐意让我的testing通过开始。
这是我的一个testing(xUnit + Moq),仅用于类似情况(使用控制器中的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);
eu-ge-ne的修改实现。 这个基于应用程序中定义的路由返回一个生成的链接。 欧格尼的例子总是返回一个固定的答案。 下面的方法将允许您testing正确的操作/控制器和路由信息正在传递到UrlHelper – 如果您正在testing对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类,这个post可能会有用。
http://www.hanselman.com/blog/ASPNETMVCSessionAtMix08TDDAndMvcMockHelpers.aspx
build立@ eu-ge-ne的答案帮了我很大的忙:
我有一个ActionResult做了一个redirect,以及一个带有FormCollection参数的UpdateModel调用。 对于UpdateModel()的工作,我不得不添加到我的Mocked HttpRequestBase:
FormCollection collection = new FormCollection(); collection["KeyName"] = "KeyValue"; request.Setup(x => x.Form).Returns(collection); request.Setup(x => x.QueryString).Returns(new NameValueCollection());
要testingredirect的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讨论了如何用unit testing覆盖所有的图层。它使用Rhino和MVC.Contrib来进行控制器的testing。 谷歌的源代码可能是一个很大的帮助。
- 在Windows 8的IIS 8上与.NET 4.5的MVC 4网站给403.14禁止的错误
- 通过AJAX将数组传递给mvc Action
- 在ASP.NET MVC DotNetOpenAuth oAuth
- 如何发布与JSON,jQuery的ASP.NET MVC控制器的复杂对象的数组?
- 全球ASAX – 获取服务器名称
- 在ASP.NET MVC中,我如何使用C#代码中的Razor @ Url.Content()助手?
- 在ASP.NET中实现文件下载时如何处理文件stream?
- 仍然可以在ASP.NET MVC中使用会话variables,或者有一些更好的select(如购物车)
- 更好的方法来加载2下拉列表中的MVC