在单元测试期间渲染视图 - ControllerContext.DisplayMode

Phi*_*tle 7 c# asp.net-mvc unit-testing rhino-mocks asp.net-mvc-4

我正在开发一个ASP.NET MVC 4 Web应用程序,它可以生成大而复杂的报告.我想编写单元测试来渲染视图,以确保视图不会爆炸,具体取决于模型:

 [Test]
 public void ExampleTest(){                  
     var reportModel = new ReportModel();

     var reportHtml = RenderRazorView(
           @"..\..\Report.Mvc\Views\Report\Index.cshtml", 
           reportModel);

     Assert.IsFalse(
         string.IsNullOrEmpty(reportHtml),
         "View Failed to Render!");          
 }

 public string RenderRazorView(string viewPath, object model){
    //WHAT GOES HERE?
 }
Run Code Online (Sandbox Code Playgroud)

我已经在网络上看到了很多有关这方面的信息,但它要么反对测试竞争,要么只能在Web请求的上下文中使用.

  • 反对 - 单元测试视图? - 结论在视图中应该没有逻辑,因此您只需要测试编译.我认为测试View是有价值的,以确保没有Null Reference Exceptions,显示正确的部分等.
  • Web请求的上下文 - 将视图呈现为字符串 - 这是为了呈现要在电子邮件中发送的视图.但是这种方法需要通过Web请求(即有效的HttpContextBase)来调用.

我一直在努力调整渲染视图作为字符串来处理Mocked HttpContextBase,但在使用Mocked时遇到了问题ControllerContext:

你调用的对象是空的.在System.Web.Mvc.VirtualPathProviderViewEngine.GetPath(ControllerContext controllerContext,String [] locations,String [] areaLocations的System.Web.Mvc.ControllerContext.get_DisplayMode()上的System.Web.WebPages.DisplayModeProvider.GetDisplayMode(HttpContextBase context)中, String locationsPropertyName,String name,String controllerName,String cacheKeyPrefix,Boolean useCache,String []&searchingLocations)

这是我到目前为止的代码:

    public string RenderRazorView(string viewPath, object model)
    {
        var controller = GetMockedDummyController();

        //Exception here
        var viewResult = 
            ViewEngines.Engines.FindView(controller.ControllerContext, "Index", "");

        using (var sw = new StringWriter())
        {
            var viewContext =
                new ViewContext(
                    controller.ControllerContext,
                    viewResult.View,
                    new ViewDataDictionary(model),
                    new TempDataDictionary(),
                    sw);

            viewResult.View.Render(viewContext, sw);

            return sw.ToString();
        }
    }
Run Code Online (Sandbox Code Playgroud)

我正在构建控制器:

    private Controller GetMockedDummyController()
    {
        var HttpContextBaseMock = new Mock<HttpContextBase>();
        var HttpRequestMock = new Mock<HttpRequestBase>();
        var HttpResponseMock = new Mock<HttpResponseBase>();
        HttpContextBaseMock.SetupGet(x => x.Request).Returns(HttpRequestMock.Object);
        HttpContextBaseMock.SetupGet(x => x.Response).Returns(HttpResponseMock.Object);

        var controller = new DummyController();

        var routeData = new RouteData();
        routeData.Values.Add("controller", "Dummy");

        controller.ControllerContext = 
            new ControllerContext(
                HttpContextBaseMock.Object,
                routeData,
                controller);

        controller.Url =
            new UrlHelper(
                new RequestContext(
                    HttpContextBaseMock.Object,
                    routeData), 
                new RouteCollection());

        return controller;
    }
Run Code Online (Sandbox Code Playgroud)

DummyController只是public class DummyController : Controller {}

提供View的路径,如何从Test项目将其呈现为HTML?或者更具体地说,我该如何嘲笑ControllerContext.DisplayMode

B2K*_*B2K 5

假设您完全分离了关注点,是否有必要实例化控制器?如果没有,那么也许您可以使用RazorEngine来测试您的视图。

var contents = File.ReadAllText("pathToView"); 
var result = Razor.Parse(contents,model);
// assert here
Run Code Online (Sandbox Code Playgroud)