【发布时间】:2015-03-21 04:29:27
【问题描述】:
我正在开发一个生成大型复杂报告的 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?
}
我在网络上看到了很多关于此的信息,但它要么反对测试竞争,要么只能在网络请求的上下文中使用。
- 反对 - Unit Testing the Views? - 得出的结论是视图中不应该存在任何逻辑,因此您只需要测试编译即可。我认为测试视图以确保没有空引用异常、显示正确的部分等是有价值的。
- Web 请求的上下文 - Render a view as a string - 这是为了呈现要在电子邮件中发送的视图。但这种方法需要通过网络请求(即有效的
HttpContextBase)调用。
我一直在努力使 Render a view as a string 与 Mocked HttpContextBase 一起工作,但在使用 Mocked ControllerContext 时遇到了问题:
对象引用未设置为对象的实例。 在 System.Web.WebPages.DisplayModeProvider.GetDisplayMode(HttpContextBase 上下文) 在 System.Web.Mvc.ControllerContext.get_DisplayMode() 在 System.Web.Mvc.VirtualPathProviderViewEngine.GetPath(ControllerContext controllerContext, String[] locations, String[] areaLocations, 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;
}
DummyController 就是 public class DummyController : Controller {}
问题
给出视图的路径,我如何将它从测试项目呈现为 HTML?或者更具体地说,我怎样才能模拟出ControllerContext.DisplayMode?
【问题讨论】:
-
我遇到了类似的问题。您最终找到解决方案了吗?我也想知道如何模拟 ControllerContext.DisplayMode。
-
不幸的是,我从来没有找到一个好的解决方案来做到这一点,如果我没记错的话,我不得不放弃我的努力,因为我通过了我的 Research Spike 并且没有返回任何有用的东西。您可能想看看一些新的 ASP.NET Core 内容,因为那里的测试故事可能要好得多。他们所做的部分工作是,AFAIK 将
HttpContext隔离出来,这是这里的核心问题之一。
标签: c# asp.net-mvc asp.net-mvc-4 unit-testing rhino-mocks