#asp.net #asp.net-mvc #asp.net-mvc-3 #routing #asp.net-mvc-routing
#asp.net #asp.net-mvc #asp.net-mvc-3 #маршруты #asp.net-mvc-routing
Вопрос:
Я сталкиваюсь со странным поведением при модульном тестировании контроллера. Я использую некоторые методы расширения для создания Url.Action, и все работает хорошо при запуске кода в рабочей среде, но модульный тест завершается неудачей. На самом деле мой пользовательский Url.Action helper использует метод :
System.Web.Routing.RouteCollection.GetVirtualPathData
точная строка :
VirtualPathData localizedPathData = HtmlExtensions.GetVirtualPathData(newRouteTable, Url.RequestContext, routingValues);
url-адрес строки = localizedPathData.VirtualPath.ToLower();
Проблема в том, что при модульном тестировании localizedPathData.VirtualPath является пустой строкой вместо URL для маршрута, как в производственном коде. Значения маршрутизации содержат три ключа «area», «controller», «action» со значениями, связанными с контроллером / действием, для которого я хотел бы сгенерировать URL. Странно то, что localizedPathData. Свойство Route содержит правильный маршрут! Итак, почему localizedPathData.VirtualPath является пустой строкой?
Я пробовал с GetVirtualPathForArea, но результат тот же.
Я издеваюсь с помощью MvcContrib TestControllerBuilder.
Пример кода здесь :
// Arrange
var loginInput = new LoginInput { EmailAddress = "test@test.fr", Password = "test", RememberMe = false };
new RouteConfigurator().RegisterRoutes(() => new ResumeAreaRegistration().RegisterArea(new AreaRegistrationContext("Resume", RouteTable.Routes)));
var testControllerBuilder = new TestControllerBuilder();
var loginController = testControllerBuilder.CreateController<LoginController>();
loginController.Url = new UrlHelper(new RequestContext(loginController.HttpContext, new RouteData()), RouteTable.Routes);
loginController.Url.RequestContext.RouteData.Values.Add("area","Resume");
loginController.Url.RequestContext.RouteData.Values.Add("culture","en-US");
const string defaultUrl = "/Dashboard";
// act
var result = loginController.Index(loginInput, null);
// assert
result.ShouldNotBeNull();
result.AssertHttpRedirect().Url.ShouldBe(defaultUrl);
Может быть, я что-то упускаю? Я о чем-то забыл?
Заранее благодарю вас за вашу помощь.
Ответ №1:
Я искал с помощью Reflector и обнаружил, что причина, по которой он не работает, заключается в том, что внутренне объект RouteCollection вызывает метод ApplyAppPathModifier в HttpResponseBase. Исправлением было бы установить ожидание в методе ApplyAppPathModifier макета HttpResponseBase, чтобы просто возвращать значение, которое передается в него. Если вы используете Rhino Mocks, то это будет выглядеть следующим образом:
loginController.HttpContext.Response.Stub(x => x.ApplyAppPathModifier(Arg<string>.Is.Anything)).IgnoreArguments().Do((Func<string, string>)((arg) => { return arg; }));