我在单元测试控制器时遇到一种奇怪的行为。 我正在使用一些扩展方法来构建Url.Action,并且在生产中运行代码时一切正常,但单元测试失败。 实际上我的自定义Url.Action助手正在使用以下方法:
System.Web.Routing.RouteCollection.GetVirtualPathData
确切的行是:
VirtualPathData localizedPathData = HtmlExtensions.GetVirtualPathData(newRouteTable, Url.RequestContext,routingValues);
string url = localizedPathData.VirtualPath.ToLower();
问题在于,虽然单元测试localizedPathData.VirtualPath是空字符串,而是生产代码中的路径网址。 routingValues包含三个键“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);
也许我错过了什么?我忘记了什么?
提前感谢您的帮助。
答案 0 :(得分:1)
我正在寻找Reflector并发现它无法工作的原因是RouteCollection对象在内部调用HttpResponseBase上的ApplyAppPathModifier方法。修复是在HttpResponseBase mock的ApplyAppPathModifier方法上设置一个期望,只返回传递给它的值。如果您使用的是Rhino Mocks,那么它将如下所示:
loginController.HttpContext.Response.Stub(x => x.ApplyAppPathModifier(Arg<string>.Is.Anything)).IgnoreArguments().Do((Func<string, string>)((arg) => { return arg; }));