在单元测试期间渲染视图
我正在研究一个生成大型复杂报表的ASP.NET MVC 4 Web应用程序。 我想编写单元测试来渲染视图,以确保视图不会炸毁,具体取决于模型:
[Test]
public void ExampleTest(){
var reportModel = new ReportModel();
var reportHtml = RenderRazorView(
@"....Report.MvcViewsReportIndex.cshtml",
reportModel);
Assert.IsFalse(
string.IsNullOrEmpty(reportHtml),
"View Failed to Render!");
}
public string RenderRazorView(string viewPath, object model){
//WHAT GOES HERE?
}
我已经在网络上看到了很多关于这方面的信息,但它要么反对测试,要么只能在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上下文) String locationsPropertyName,String name,String controllerName,String cacheKeyPrefix,Boolean useCache,String []&SearchesLocations)
这是我迄今为止的代码:
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;
}
DummyController
只是public class DummyController : Controller {}
题
为View提供路径,我怎样才能从Test项目中将它渲染为HTML? 或者更具体地说,我怎样才能模拟出ControllerContext.DisplayMode
?
假设你完全分离了关注点,是否有必要实例化控制器? 如果没有,那么也许你可以使用RazorEngine来测试你的视图。
var contents = File.ReadAllText("pathToView");
var result = Razor.Parse(contents,model);
// assert here
你将需要一个空的Controller
来测试(例如TestController
)
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();
}
}
链接地址: http://www.djcxy.com/p/83161.html
上一篇: Render a View during a Unit Test
下一篇: Nonblocking fifo