2013-10-24 3 views
3

필자가 작성한 사용자 정의 뷰 엔진을 단위 테스트하려고합니다.유닛 테스트 사용자 정의 뷰 엔진

:

뷰 엔진의 의도 된 기능은베이스 RazorViewEngine 여기

FindView

수행 할 때 보이는 귀찮게

public void ViewEngineReturnsDependencyView() 
{ 
    //Mock http request 
    var mockRequest = new Mock<HttpRequestBase>(); 
    //Mock server variable 
    NameValueCollection variables = new NameValueCollection(); 
    variables.Add("APPL_PHYSICAL_PATH", TEST_APPLICATION_PATH); 
    mockRequest.Setup(r => r.ServerVariables).Returns(variables); 

    //Mock http context 
    var mockHttpContext = new Mock<HttpContextBase>(); 

    //Mock route 
    mockHttpContext.Setup(c => c.Request).Returns(mockRequest.Object); 
    var routeData = new RouteData(); 
    routeData.Values.Add("controller", "testController"); 
    routeData.Values.Add("action", "testAction"); 

    //Mock controller context 
    var controllerContext = new testController().ControllerContext; 
    controllerContext.HttpContext = mockHttpContext.Object; 
    controllerContext.RouteData = routeData; 
    var mockControllerContext = new ControllerContext(mockHttpContext.Object, 
         routeData, 
         new Mock<ControllerBase>().Object); 

    //Run find view 
    viewEngine.FindView(mockControllerContext, "TestView", null, false); 
} 

viewEngine.FindView(...); 내 단위 테스트이다 변경 예외를 발생한다는 것이다

테스트 메서드 ... throw 예외 : System.NullReferenceException : 개체 참조가 개체의 인스턴스로 설정되지 않았습니다. 결과 스택 트레이스 : System.Web.WebPages.DisplayModeProvider.GetDisplayMode System.Web.Mvc.VirtualPathProviderViewEngine.GetPathFromGeneralName (ControllerContext controllerContext, List`1 위치, 문자열 이름, 문자열 컨트롤러 명에서 (HttpContextBase 컨텍스트)

에서

문자열 AREANAME 문자열 cacheKey 문자열 [] & searchedLocations) System.Web.Mvc.VirtualPathProviderViewEngine.GetPath (controllerContext controllerContext에서

문자열 [] 위치 문자열 [] areaLocations 문자열 locationsPropertyName 문자열 이름 문자열 컨트롤러 명, String cacheKeyPrefix, Boolean useCache 문자열 [] & searchedLocations) ...의 Mvc.CustomRazorViewEngine.FindView System.Web.Mvc.VirtualPathProviderViewEngine.FindView (ControllerContext controllerContext 문자열 viewName과 문자열 마스터 이름, 부울 useCache)

에서

(ControllerContext controllerContext , 문자열 viewName, 문자열 masterName, 부울 useCache) ... \ Mvc \ CustomRazorViewEngine.cs : line 85

at ... Tests.MVC.ViewEngine.ViewEngineReturnsDependencyView() ... Tests \ MVC \ ViewEngine. cs : 줄 78

제 질문은, 어떻게 단위 테스트 RazorViewEngine.FindView()에 적절한 mock을 만드나요?

답변

6

HttpContext.Items 메서드를 사용하는 경우 해당 속성을 모의 처리해야합니다.

시도 :

mockHttpContext.Setup(c => c.Items).Returns(new Dictionary<object, object>()); 
2

늦어서 가능 해요 것을 알고,하지만 난 같은 문제가 있었다. 몇 가지 연구를 한 후 Microsoft 팀이 면도기 엔진을 테스트 한 방법을 발견했습니다. 여기에서 찾을 수 있습니다 : http://aspnetwebstack.codeplex.com/SourceControl/latest#test/System.Web.Mvc.Test/Test/RazorViewEngineTest.cs 기본적인 아이디어는 명시 적으로 뷰 엔진의 보호 된 메소드를 노출하는 테스트 가능한 뷰 엔진 스텁을 만드는 것입니다. ir는 TestableRazorViewEngine이라고 불리며 파일의 끝 부분에서 찾을 수 있습니다. 나는 그것을 나의 필요에 따라 조금 바꿨다. 필자는 모든 스텁 뷰 엔진의 컨트롤러 컨트롤러 메타 데이터를 내 뷰 엔진에 전달하기 위해 ControllerContext 유형의 메서드에 3 번째 인수를 추가했습니다. 이것은 내가 그랬던 방식입니다 :

[Fact] 
public void CreatePartialView_ViewNameWithoutReplacementToken_ReturnsOriginalPath() 
{ 
    var engine = new TestableViewEngine(); 
    var view = (RazorView)engine.CreatePartialView("partial path", new ControllerContext()); 
    Assert.Equals("partial path", view.ViewPath); 
} 

[Fact] 
public void CreatePartialView_ViewNameWithReplacementToken_ReturnsViewWithTokenReplacedByControllerNamespace() 
{ 
    var engine = new TestableViewEngine(); 
    var controller = new DummyController(); 
    var controllerContext = new ControllerContext { Controller = controller }; 
    var view = (RazorView)engine.CreatePartialView("partial path %1", controllerContext); 
    Assert.Equals("partial path Stub/Tests/Controllers", view.ViewPath); 
} 
+0

답변 해 주셔서 감사합니다. 이걸 보면서 너무 오랜 시간이 걸렸습니다. 나는 당신의 답을 옳은지 확인할 수 없었습니다. 당신의 대답이 다른 사람들에게 도움이된다면 나는 그것을 올바른 것으로 표시 할 것입니다. – MrJD

관련 문제