如何用FakeItEasy伪造ASP.NET MVC的UrlHelper解决返回null问题
解决UrlHelper.Action返回null的FakeItEasy配置方案
核心问题原因
Url.Action是UrlHelper的扩展方法,FakeItEasy无法直接拦截扩展方法调用,需针对扩展方法内部实际调用的UrlHelper.RouteUrl实例方法做配置。
正确配置步骤
假设你的控制器类名为PackagesController,测试代码按以下方式调整:
初始化控制器与伪造依赖
[TestMethod] public void EditPackageDetails_Should_Return_Correct_Redirect() { // 创建控制器实例 var controller = new PackagesController(); // 伪造ControllerContext(UrlHelper依赖此上下文) var fakeControllerContext = A.Fake<ControllerContext>(); controller.ControllerContext = fakeControllerContext; // 伪造UrlHelper,传入伪造的RequestContext var fakeRequestContext = A.Fake<RequestContext>(); var fakeUrlHelper = A.Fake<UrlHelper>(fakeRequestContext);配置RouteUrl方法的返回值
匹配Action("PackagesList", "Packages")对应的路由参数,指定返回目标URL:// 配置当调用RouteUrl并传入指定路由参数时,返回预期URL A.CallTo(() => fakeUrlHelper.RouteUrl( A<object>.That.Matches(routeValues => ((dynamic)routeValues).action == "PackagesList" && ((dynamic)routeValues).controller == "Packages"))) .Returns("/Packages/PackagesList");绑定伪造的UrlHelper到控制器
// 将伪造的UrlHelper赋值给控制器的Url属性 controller.Url = fakeUrlHelper; // 执行测试方法 var result = controller.EditPackageDetails(/* 传入测试参数 */) as RedirectResult; // 断言验证 Assert.IsNotNull(result); Assert.AreEqual("/Packages/PackagesList", result.Url); }
替代简化方案(直接创建真实UrlHelper)
如果不需要严格伪造,也可以手动创建真实的UrlHelper实例,避免配置FakeItEasy的复杂逻辑:
var routes = new RouteCollection(); // 注册你的路由(和项目中RouteConfig一致) RouteConfig.RegisterRoutes(routes); var requestContext = new RequestContext(new HttpContextWrapper(HttpContext.Current), new RouteData()); var realUrlHelper = new UrlHelper(requestContext, routes); controller.Url = realUrlHelper;
这种方式会真实生成路由URL,适合路由规则固定的场景。
内容的提问来源于stack exchange,提问作者jdistro07
相关产品推荐
相关产品推荐

