试图做一些控制器在我的ASP.NET MVC 3 Web应用程序单元测试。
我的测试是这样的:
[TestMethod的]公共无效Ensure_CreateReviewHttpPostAction_RedirectsAppropriately(){ //安排。 变种newReview = CreateMockReview(); //法案。 VAR的结果= _controller.Create(newReview)为RedirectResult; //断言。 Assert.IsNotNull(结果,RedirectResult不退换);}pretty简单。基本上测试 [HttpPost] 行动,以确保它返回一个 RedirectResult (PRG模式)。我没有使用 RedirectToRouteResult 因为没有超载的支持锚链接。上移动。
现在,我使用的起订量以嘲笑HTTP上下文,包括服务器变量,控制器上下文,会话等一切正常为止。
直到我已经打了这条线在我的操作方法:
返回重定向(Url.LandingPageWithAnchor(someObject.Uri,review.Uri);LandingPageWithAnchor 是一个自定义的HTML帮助:
公共静态字符串LandingPageWithAnchor(这UrlHelper帮手,串uri1,串uri2){ 常量字符串网址格式={0}#{1}; 返回的String.Format(网址格式, helper.RouteUrl(LANDING_PAGE,新的{URI = uri1}) uri2);}基本上,我重定向到另一个网页,其中一个是登陆页的新内容,对新的审查锚。酷。
现在,这个方法之前,因为 UrlHelper 为null失败。
所以我做这在我的嘲弄:
controller.Url =新UrlHelper(fakeRequestContext);这得到了进一步,但现在它的失败,因为路由表不包含定义LANDING_PAGE。
所以我知道我需要模拟东西,但林不知道,如果它是:
一)路由表二)UrlHelper.RouteUrl方法三)UrlHelper.LandingPageWithAnchor扩展方法我写了
任何人都可以提供一些指导?
修改
这特别的路线是在区,所以我打过电话的区域登记我的单元测试:
AreaRegistration.RegisterAllAreas();但我得到一个出现InvalidOperationException :
这方法不能在应用程序的pre-启动初始化阶段被调用。
解决方案得到它通过嘲讽的HttpContext,RequestContext的和ControllerContext工作,注册路线然后创建一个 UrlHelper 这些路由。
去有点像这样:
公共静态无效SetFakeControllerContext(此控制器控制器,HttpContextBase httpContextBase){ VAR的HttpContext = httpContextBase? FakeHttpContext()对象。 VAR的RequestContext =新的RequestContext(HttpContext的,新的RouteData()); VAR controllerContext =新的ControllerContext(RequestContext的控制器); MvcApplication.RegisterRoutes(); controller.ControllerContext = controllerContext; controller.Url =新UrlHelper(RequestContext的,RouteTable.Routes);}FakeHttpContext()是一个起订量帮手创造所有的东西模拟,服务器变量,会话等。
Trying to do some controller unit-testing in my ASP.NET MVC 3 web application.
My test goes like this:
[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"); }Pretty simple. Basically testing a [HttpPost] action to ensure it returns a RedirectResult (PRG pattern). I'm not using RedirectToRouteResult because none of the overloads support anchor links. Moving on.
Now, i'm using Moq to mock the Http Context, including server variables, controller context, session, etc. All going well so far.
Until i've hit this line in my action method:
return Redirect(Url.LandingPageWithAnchor(someObject.Uri, review.Uri);LandingPageWithAnchor is a custom HTML helper:
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); }Basically, i redirect to another page which is a "landing page" for new content, with an anchor on the new review. Cool.
Now, this method was failing before because UrlHelper was null.
So i did this in my mocking:
controller.Url = new UrlHelper(fakeRequestContext);Which got it further, but now it's failing because the route tables don't contain a definition for "Landing_Page".
So i know i need to mock "something", but im not sure if it's:
a) The route tables b) The UrlHelper.RouteUrl method c) The UrlHelper.LandingPageWithAnchor extension method i wrote
Can anyone provide some guidance?
EDIT
This particular route is in an Area, so i tried calling the area registration in my unit test:
AreaRegistration.RegisterAllAreas();But i get an InvalidOperationException:
This method cannot be called during the application's pre-start initialization stage.
解决方案
Got it working by mocking the HttpContext, RequestContext and ControllerContext, registering the routes then creating a UrlHelper with those routes.
Goes a little like this:
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() is a Moq helper which creates all the mock stuff, server variables, session, etc.
更多推荐
ASP.NET MVC控制器单元测试
发布评论