尝试在我的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 等。