Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在单元测试期间呈现视图-ControllerContext.DisplayMode_C#_Asp.net Mvc_Asp.net Mvc 4_Unit Testing_Rhino Mocks - Fatal编程技术网

C# 在单元测试期间呈现视图-ControllerContext.DisplayMode

C# 在单元测试期间呈现视图-ControllerContext.DisplayMode,c#,asp.net-mvc,asp.net-mvc-4,unit-testing,rhino-mocks,C#,Asp.net Mvc,Asp.net Mvc 4,Unit Testing,Rhino Mocks,我正在开发一个ASP.NET MVC 4 web应用程序,它可以生成大型复杂的报告。我想编写渲染视图的单元测试,以确保视图不会因模型而异: [Test] public void ExampleTest(){ var reportModel = new ReportModel(); var reportHtml = RenderRazorView( @"..\..\Report.Mvc\Views\Report\I

我正在开发一个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?
 }
我在web上看到了很多关于这方面的信息,但它要么反对测试VIE,要么只能在web请求的上下文中使用

  • 反对——这得出结论,视图中不应该有逻辑,所以您只需要测试编译。我认为测试视图是有价值的,以确保没有空引用异常,显示了正确的部分,等等
  • Web请求的上下文--这是呈现要在电子邮件中发送的视图。但这种方法需要通过web请求(即有效的
    HttpContextBase
    )调用
我一直在努力适应使用模拟的
HttpContextBase
,但在使用模拟的
ControllerContext
时遇到了问题:

对象引用未设置为对象的实例。 位于System.Web.WebPages.DisplayModeProvider.GetDisplayMode(HttpContextBase上下文) 在System.Web.Mvc.ControllerContext.get_DisplayMode()中 位于System.Web.Mvc.VirtualPathProviderViewEngine.GetPath(ControllerContext ControllerContext,String[]位置,String[]区域位置,String locationsPropertyName,String name,String controllerName,String cacheKeyPrefix,Boolean useCache,String[]和searchedLocations)

这是我目前掌握的代码:

    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();
        }
    }
我正在构建控制器:

    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;
    }
专用控制器GetMockedDummyController()
{
var HttpContextBaseMock=new Mock();
var HttpRequestMock=new Mock();
var HttpResponseMock=new Mock();
SetupGet(x=>x.Request).Returns(HttpRequestMock.Object);
HttpContextBaseMock.SetupGet(x=>x.Response).Returns(HttpResponseMock.Object);
var controller=new DummyController();
var routeData=新routeData();
添加(“控制器”、“虚拟”);
controller.ControllerContext=
新控制器上下文(
HttpContextBaseMock.Object,
罗特达塔,
控制器);
controller.Url=
新UrlHelper(
新请求上下文(
HttpContextBaseMock.Object,
路特达),
新路线收集());
返回控制器;
}
DummyController
只是
公共类DummyController:Controller{}

问题


给出视图的路径,如何从测试项目将其呈现为HTML?或者更具体地说,我如何模拟
ControllerContext.DisplayMode

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

var contents = File.ReadAllText("pathToView"); 
var result = Razor.Parse(contents,model);
// assert here

您需要一个空的
控制器
用于测试(例如
TestController

公共类WebMvcHelpers
{
公共静态字符串GetViewPageHtml(对象模型,字符串viewName)
{
System.Web.Mvc.Controller=CreateController();
ViewEngineResult结果=ViewEngines.Engines.FindPartialView(controller.ControllerContext,viewName);
如果(result.View==null)
抛出新异常(string.Format(“未找到视图页{0}”,viewName));
controller.ViewData.Model=模型;
StringBuilder sb=新的StringBuilder();
使用(StringWriter sw=新StringWriter(sb))
{
使用(System.Web.UI.HtmlTextWriter输出=新的System.Web.UI.HtmlTextWriter(sw))
{
ViewContext ViewContext=新的ViewContext(controller.ControllerContext、result.View、controller.ViewData、controller.TempData、output);
result.View.Render(viewContext,输出);
}
}
使某人返回字符串();
}
/// 
///从头创建MVC控制器的实例
///当不存在现有ControllerContext时
/// 
///要创建的控制器的类型
/// 
公共静态T CreateController(RouteData RouteData=null)
其中T:System.Web.Mvc.Controller,new()
{
T控制器=新的T();
//创建MVC控制器上下文
HttpContextBase包装器=null;
if(HttpContext.Current!=null)
包装器=新的HttpContextWrapper(System.Web.HttpContext.Current);
//否则
//包装器=CreateHttpContextBase(编写器);
if(routeData==null)
RoutedData=新RoutedData();
如果(!routeData.Values.ContainsKey(“控制器”)和&!routeData.Values.ContainsKey(“控制器”))
routeData.Values.Add(“controller”,controller.GetType().Name
.ToLower()
.更换(“控制器”);
controller.ControllerContext=new System.Web.Mvc.ControllerContext(包装器、路由数据、控制器);
返回控制器;
}
}
公共类TestController:控制器
{
公共行动结果索引()
{
返回视图();
}
}

no,我不需要调用控制器或其方法。我已经有了一个模型,想用它来渲染一个视图,所以我要试试这个!您是否使用此选项渲染“MVC”视图。我无法让它编译像
@Styles.Render()
这样的语句。引擎抱怨它缺少程序集,即使我已经添加了它们。查看编译后的输出后,看起来正在基于web.config
system.web\pages\namespace
添加using语句。有没有办法添加这些内容?RazorEngine链接中有文档讨论了如何使用ha
public class WebMvcHelpers
{
    public static string GetViewPageHtml(object model, string viewName)
    {
        System.Web.Mvc.Controller controller = CreateController<TestController>();

        ViewEngineResult result = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);

        if (result.View == null)
            throw new Exception(string.Format("View Page {0} was not found", viewName));

        controller.ViewData.Model = model;
        StringBuilder sb = new StringBuilder();
        using (StringWriter sw = new StringWriter(sb))
        {
            using (System.Web.UI.HtmlTextWriter output = new System.Web.UI.HtmlTextWriter(sw))
            {
                ViewContext viewContext = new ViewContext(controller.ControllerContext, result.View, controller.ViewData, controller.TempData, output);
                result.View.Render(viewContext, output);
            }
        }

        return sb.ToString();
    }

    /// <summary>
    /// Creates an instance of an MVC controller from scratch 
    /// when no existing ControllerContext is present       
    /// </summary>
    /// <typeparam name="T">Type of the controller to create</typeparam>
    /// <returns></returns>
    public static T CreateController<T>(RouteData routeData = null)
                where T : System.Web.Mvc.Controller, new()
    {
        T controller = new T();

        // Create an MVC Controller Context
        HttpContextBase wrapper = null;
        if (HttpContext.Current != null)
            wrapper = new HttpContextWrapper(System.Web.HttpContext.Current);
        //else
        //    wrapper = CreateHttpContextBase(writer);


        if (routeData == null)
            routeData = new RouteData();

        if (!routeData.Values.ContainsKey("controller") && !routeData.Values.ContainsKey("Controller"))
            routeData.Values.Add("controller", controller.GetType().Name
                                                        .ToLower()
                                                        .Replace("controller", ""));

        controller.ControllerContext = new System.Web.Mvc.ControllerContext(wrapper, routeData, controller);
        return controller;
    }
}

public class TestController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
}