2009-09-02 6 views
21

ASP.NET MVC 앱의 메뉴 URL은 컨트롤러/액션에서 생성됩니다. 그래서 그들은ASP.NET MVC : 모의 controller.Url.Action

이라고 부릅니다.
controller.Url.Action(action, controller) 

이제 단위 테스트에서 어떻게 작동합니까? 내가 성공적으로

var controller = new TestControllerBuilder().CreateController<OrdersController>(); 

와 MVCContrib를 사용하지만 NullReferenceException이 URL 때문에 == null를 실패 나는 controller.Url.Action (액션, 컨트롤러)를 얻을 그것으로 수행하려고 뭐든간에.

업데이트 : HttpContext를 가로채는 방법이 아닙니다. MVCContrib, Scott Hanselman의 위조 사례 및 http://stephenwalther.com/blog/archive/2008/07/01/asp-net-mvc-tip-12-faking-the-controller-context.aspx의 예제를 사용하여 여러 가지 방법으로이 작업을 수행했습니다. 내가 가짜 값을 알아야하기 때문에 이것은 도움이되지 않습니다 ... ApplicationPath입니까? 어떻게 설정해야합니까? 호출 된 컨트롤러/액션과 일치해야합니까? 즉, Url.Action은 어떻게 작동하며 어떻게 만족합니까?

나는 또한 IUrlActionAbstraction을 할 수 있고 그걸로 갈 수 있다는 것을 알고있다. 그러나 나는 이것을하고 싶지 않다. 결국, 나는 MVCContrib/Mock의 전체 능력을 가지고 있으며 또 다른 추상화가 필요한 이유는 무엇입니까?

var routes = new RouteCollection(); 
MvcApplication.RegisterRoutes(routes); 
HomeController controller = CreateController<HomeController>(); 

controller.HttpContext.Response 
    .Stub(x => x.ApplyAppPathModifier("/Home/About")) 
    .Return("/Home/About"); 

controller.Url = new UrlHelper(
    new RequestContext(
     controller.HttpContext, new RouteData() 
    ), 
    routes 
); 
var url = controller.Url.Action("About", "Home"); 
Assert.IsFalse(string.IsNullOrEmpty(url)); 
+0

테스트 스위트는 무엇입니까? –

+1

답변 자체는 가치가 없으므로 비슷한 대답을 가리키고 있습니다. http://bit.ly/aSJ0a –

+0

예 해당 링크를 사용했는데 작동하지 않았습니다. 사실 나는 Scott의 버전과 MVCContrib를 모두 시도했다. 내가 이해하려고하는 것은 설정해야 할 가치가 무엇입니까? Url.Action()이 실제로 사용하는 것은 무엇입니까? 나는. 당신이 제공 한 링크에 많은 변수를 설정하는 Moq 버전이 있습니다 ... 모두 필요합니까? 나는 행운이없이 그들 모두를 시험해 보았다. – queen3

답변

21

는 MvcContrib의 TestControllerBuilder 사용 UrlHelper을 조롱 수있는 방법은 당신이 Moq 사용하는 경우

var fakeUrlHelper = A.Fake<UrlHelper>(); 
     controller.Url = fakeUrlHelper; 
     A.CallTo(() => fakeUrlHelper.Action(A<string>.Ignored, A<string>.Ignored)) 
      .Returns("/Action/Controller"); 
+0

죄송합니다 ... Controller.Url에 대한 MSDN 도움말에서 "URL 도우미 개체를 가져옵니다."라는 오해의 여지가있었습니다. 설정 도구가 있는지 확인하지 않았습니다. – queen3

+0

우리는 MVC4 Darin으로 어떻게 이것을 달성 할 수 있었는지 알고 있습니까? 귀하의 코드 예제를 따르려고 시도하지만 RegisterRoutes를 호출 할 수 없습니다. – DevDave

+2

Tyler : RegisterRoutes는 관습에 따라 MvcApplication.RouteTable.Routes.Add (...) – Shane

3

가짜 그것을 쉽게 작품을 잘 : 여기

+0

을 사용하여 'FakeItEasy'를 사용합니다. 하지만 ... '액션'방법은 가상이 아닙니다 ... 어떻게 가짜를 가로 챌 수 있습니까? –

3

을 (그리고 MvcContrib을의 TestControllerBuilder)을 @ DarianDimitrov의 답변과 비슷한 상황을 조롱 할 수 있습니다.

var controller = new OrdersController(); 
var context = new Mock<System.Web.HttpContextBase>().Object; 

controller.Url = new UrlHelper(
    new RequestContext(context, new RouteData()), 
    new RouteCollection() 
); 

controller.HttpContext 속성을 설정하지 않지만 Url.Action을 실행할 수 있으며 빈 문자열을 반환하므로 조롱은 필요하지 않습니다.

13

단지 MOQ를 사용한다이 할 수있는 청소기 방법 (또는 당신이 좋아하는 다른 프레임 워크)

var controller = new OrdersController(); 
var Mock<UrlHelper> UrlHelperMock = new Mock<UrlHelper>(); 

controller.Url = UrlHelperMock.Object; 

UrlHelperMock.Setup(x => x.Action("Action", "Controller", new {parem = "test"})).Returns("testUrl"); 

var url = controller.Url.Action("Action", "Controller", new {parem = "test"}); 
assert.areEqual("/Controller/Action/?parem=test",url); 

깨끗하고 간단한 UrlHelper 자체를 조롱.