ASP.NET MVC控制器单元测试 - UrlHelper扩展问题

RPM*_*984 15 c# asp.net-mvc unit-testing moq asp.net-mvc-routing

尝试在我的ASP.NET MVC 3 Web应用程序中进行一些控制器单元测试.

我的测试是这样的:

[TestMethod]
public void Ensure_CreateReviewHttpPostAction_RedirectsAppropriately()
{
   // Arrange.
   var newReview = CreateMockReview();

   // Act.
   var result = _controller.Create(newReview) as RedirectResult;

   // Assert.
   Assert.IsNotNull(result, "RedirectResult was not returned");
}
Run Code Online (Sandbox Code Playgroud)

很简单.基本上测试一个[HttpPost]动作以确保它返回一个RedirectResult(PRG模式).我没有使用,RedirectToRouteResult因为没有任何重载支持锚链接.继续.

现在,我正在使用Moq来模拟Http Context,包括服务器变量,控制器上下文,会话等.到目前为止一切顺利.

直到我在我的动作方法中击中了这一行:

return Redirect(Url.LandingPageWithAnchor(someObject.Uri, review.Uri);
Run Code Online (Sandbox Code Playgroud)

LandingPageWithAnchor 是一个自定义HTML帮助器:

public static string LandingPageWithAnchor(this UrlHelper helper, string uri1, string uri2)
{
   const string urlFormat = "{0}#{1}";

   return string.Format(urlFormat,
                helper.RouteUrl("Landing_Page", new { uri = uri1}),
                uri2);
}
Run Code Online (Sandbox Code Playgroud)

基本上,我重定向到另一个页面,这是新内容的"登陆页面",在新评论中有一个锚点.凉.

现在,这个方法之前失败了,因为它UrlHelper是null.

所以我在嘲笑中这样做了:

controller.Url = new UrlHelper(fakeRequestContext);
Run Code Online (Sandbox Code Playgroud)

更进一步,但现在它失败了,因为路由表不包含"Landing_Page"的定义.

所以我知道我需要嘲笑"某事",但我不确定它是否是:

a)路由表
b)UrlHelper.RouteUrl方法
c)我写的UrlHelper.LandingPageWithAnchor扩展方法

谁能提供一些指导?

编辑

这个特定的路线在一个区域,所以我尝试在我的单元测试中调用区域注册:

AreaRegistration.RegisterAllAreas();
Run Code Online (Sandbox Code Playgroud)

但我得到一个InvalidOperationException:

在应用程序的预启动初始化阶段期间无法调用此方法.

RPM*_*984 12

通过模拟HttpContext,RequestContext和ControllerContext来工作,注册路由然后UrlHelper用这些路由创建一个.

有点像这样:

public static void SetFakeControllerContext(this Controller controller, HttpContextBase httpContextBase)
{
    var httpContext = httpContextBase ?? FakeHttpContext().Object;
    var requestContext = new RequestContext(httpContext, new RouteData());
    var controllerContext = new ControllerContext(requestContext, controller);
    MvcApplication.RegisterRoutes();
    controller.ControllerContext = controllerContext;
    controller.Url = new UrlHelper(requestContext, RouteTable.Routes);
}
Run Code Online (Sandbox Code Playgroud)

FakeHttpContext() 是一个Moq帮助器,它创建所有模拟东西,服务器变量,会话等.

  • 我还使用了Scott Hanselman [这里]提供的Moq助手(http://www.hanselman.com/blog/ASPNETMVCSessionAtMix08TDDAndMvcMockHelpers.aspx). (2认同)