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

我的测试是这样的:

[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");
}

很简单基本上测试[HttpPost] Action ,以确保它返回RedirectResult(PRG模式)。我没有使用RedirectToRouteResult,因为所有重载都不支持 anchor 链接。继续。

现在,我正在使用 Moq 来模拟Http上下文,包括服务器变量, Controller 上下文, session 等。到目前为止一切进展顺利。

直到我在我的操作方法中达到以下要求:
return Redirect(Url.LandingPageWithAnchor(someObject.Uri, review.Uri);
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);
}

基本上,我重定向到另一个页面,该页面是新内容的“登录页面”,并带有新评论的 anchor 。凉。

现在,此方法之前失败了,因为UrlHelper为null。

所以我在 mock 中做到了这一点:
controller.Url = new UrlHelper(fakeRequestContext);

哪一个更进一步,但是现在失败了,因为路由表不包含“Landing_Page”的定义。

所以我知道我需要 mock “某物”,但我不确定是否是:

a)路线表

b)UrlHelper.RouteUrl方法

c)我编写的UrlHelper.LandingPageWithAnchor扩展方法

谁能提供一些指导?

编辑

该特定路线位于区域中,因此我尝试在单元测试中调用区域注册:
AreaRegistration.RegisterAllAreas();

但是我得到了InvalidOperationException:

最佳答案

通过模拟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);
}
FakeHttpContext()是Moq帮助程序,它创建所有模拟内容,服务器变量, session 等。

10-06 13:06