Asp.net-Mvc
在 ASP.NET MVC 中模擬 Controller.Url.Action(string, string, object, string)
我使用NUnit和Moq庫進行單元測試。我需要模擬重載的 Url.Action(string, string, object, string),因為我的控制器的操作使用它來獲取 Action 的絕對網址。
我現在的嘗試(看看MockUrlAction測試):
[TestFixture] public class ControllerTests { [Test] public void MockUrlAction() { var controller = new TestController(); controller.Url = new UrlHelper(new RequestContext(MvcMoqHelpers.FakeHttpContext(), new RouteData()), GetRouteCollection()); // it works Assert.AreEqual("/PathToAction", controller.Url.Action("TestAction")); // but it doesn't work Assert.AreEqual("http://example.com/PathToAction", controller.Url.Action("TestAction", null, null, "http")); } private RouteCollection GetRouteCollection() { BundleTable.MapPathMethod = MapBundleItemPath; var routes = new RouteCollection(); RouteConfig.RegisterRoutes(routes); var adminArea = new AdminAreaRegistration(); var adminAreaRegistrationContext = new AreaRegistrationContext(adminArea.AreaName, routes); adminArea.RegisterArea(adminAreaRegistrationContext); return routes; } } public static class MvcMoqHelpers { public static HttpContextBase FakeHttpContext() { 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>(); request.Setup(r => r.AppRelativeCurrentExecutionFilePath).Returns("/"); request.Setup(r => r.ApplicationPath).Returns("/"); response.Setup(s => s.ApplyAppPathModifier(It.IsAny<string>())).Returns<string>(s => s); 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); return context.Object; } }並且線上
Assert.AreEqual("http://example.com/PathToAction", controller.Url.Action("TestAction", null, null, "http"));我得到一個例外
System.NullReferenceException : Object reference not set to an instance of an object. at System.Web.Mvc.UrlHelper.GenerateUrl(String routeName, String actionName, String controllerName, String protocol, String hostName, String fragment, RouteValueDictionary routeValues, RouteCollection routeCollection, RequestContext requestContext, Boolean includeImplicitMvcValues) at System.Web.Mvc.UrlHelper.Action(String actionName, String controllerName, Object routeValues, String protocol)對我來說很奇怪,它
controller.Url.Action("TestAction")工作正常,但controller.Url.Action("TestAction", null, null, "http")沒有。PS MvcMoqHelpers.FakeHttpContext() 來自這裡,也許它有助於回答這個問題。
所以問題是:我怎樣才能得到 Url.Action(string, string, object, string) 的嘲笑?
謝謝。
您必須設置 Request.Url,並且您在教程中提供了這段程式碼:
public static HttpContextBase FakeHttpContext(string url) { HttpContextBase context = FakeHttpContext(); context.Request.SetupRequestUrl(url); return context; }原因是 - 在您的 Url.Action 重載中,您沒有提供主機名和協議,因此 MVC 嘗試從 Request.Url 中提取這些值
if (!String.IsNullOrEmpty(protocol) || !String.IsNullOrEmpty(hostName)) { Uri requestUrl = requestContext.HttpContext.Request.Url; protocol = (!String.IsNullOrEmpty(protocol)) ? protocol : Uri.UriSchemeHttp; hostName = (!String.IsNullOrEmpty(hostName)) ? hostName : requestUrl.Host;