MVC 3 单元测试控制器,但 GetVirtualPathData 发送奇怪的 VirtualPathData 结果

发布于 2024-11-09 16:52:13 字数 1906 浏览 5 评论 0原文

在对控制器进行单元测试时,我遇到了奇怪的行为。 我正在使用一些扩展方法来构建 Url.Action,并且在生产中运行代码时一切正常,但单元测试失败。 事实上,我的自定义 Url.Action 助手正在使用以下方法:

System.Web.Routing.RouteCollection.GetVirtualPathData

确切的行是:

VirtualPathData localizedPathData = HtmlExtensions.GetVirtualPathData(newRouteTable, Url.RequestContext、routingValues);

字符串网址 = localizedPathData.VirtualPath.ToLower();

问题是,在单元测试时,localizedPathData.VirtualPath 是一个空字符串,而不是像生产代码中那样的路由 url。 routingValues 包含三个键“area”、“controller”、“action”,以及我想要生成的 url 的控制器/操作的相关值。 奇怪的是 localizedPathData.Route 属性包含正确的路线!那么为什么 localizedPathData.VirtualPath 是一个空字符串?

我尝试使用 GetVirtualPathForArea 但结果是相同的。

我正在嘲笑 MvcContrib TestControllerBuilder。

示例代码在这里:

    // Arrange 
var loginInput = new LoginInput { EmailAddress = "[email protected]", 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);

也许我遗漏了一些东西?我忘记了什么?

预先感谢您的帮助。

I'm encountering a strange behaviour when unit testing controller.
I'm using some extension methods for building Url.Action and all works well when runing code in production but the unit test fails.
In fact my custom Url.Action helper is using the method :

System.Web.Routing.RouteCollection.GetVirtualPathData

the exact line is :

VirtualPathData localizedPathData =
HtmlExtensions.GetVirtualPathData(newRouteTable,
Url.RequestContext, routingValues);

string url =
localizedPathData.VirtualPath.ToLower();

The problem is that while unit testing the localizedPathData.VirtualPath is an empty string instead the url for the route like in the production code. The routingValues contains three keys "area", "controller", "action" with related values to the controller/action that I would like to have a url generated to.
What's strange is that localizedPathData.Route property contains the correct route ! So why the localizedPathData.VirtualPath is an empty string ?

I tried with GetVirtualPathForArea but the result is the same.

I'm mocking with MvcContrib TestControllerBuilder.

The sample code is here :

    // Arrange 
var loginInput = new LoginInput { EmailAddress = "[email protected]", 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);

Maybe I'm missing something ? Something I forgot about ?

Thank you in advance for your help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

双马尾 2024-11-16 16:52:13

我正在使用 Reflector 进行查找,发现它不起作用的原因是 RouteCollection 对象在内部调用 HttpResponseBase 上的 ApplyAppPathModifier 方法。解决方法是对 HttpResponseBase 模拟的 ApplyAppPathModifier 方法设置一个期望,以仅返回传递给它的值。如果您使用 Rhino Mocks,那么它看起来像这样:

loginController.HttpContext.Response.Stub(x => x.ApplyAppPathModifier(Arg<string>.Is.Anything)).IgnoreArguments().Do((Func<string, string>)((arg) => { return arg; }));

I was looking with Reflector and found that the reason it isn't working is that internally the RouteCollection object calls the ApplyAppPathModifier method on HttpResponseBase. The fix would be to setup an expectation on the ApplyAppPathModifier method of the HttpResponseBase mock to just return the value that is passed into it. If you are using Rhino Mocks, then it would look like this:

loginController.HttpContext.Response.Stub(x => x.ApplyAppPathModifier(Arg<string>.Is.Anything)).IgnoreArguments().Do((Func<string, string>)((arg) => { return arg; }));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文