单元测试自定义视图引擎

本文关键字:引擎 视图 自定义 单元测试 | 更新日期: 2023-09-27 18:36:50

我正在尝试对我编写的自定义视图引擎进行单元测试。

视图引擎的预期功能是,它在执行 FindView 时会更改基本 RazorViewEngine 的外观。

这是我的单元测试

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(...);抛出了一个异常:

测试方法...引发异常:System.NullReferenceException:对象引用未设置为对象的实例。结果堆栈跟踪:

at System.Web.WebPages.DisplayModeProvider.GetDisplayMode(HttpContextBase context)

at System.Web.Mvc.VirtualPathProviderViewEngine.GetPathFromGeneralName(ControllerContext controllerContext, List'1 locations, String name, String controllerName, String areaName, String cacheKey, String[]& searchedLocations)

at System.Web.Mvc.VirtualPathProviderViewEngine.GetPath(ControllerContext controllerContext, String[] locations, String[] areaLocations, String locationsPropertyName, String name, String controllerName, String cacheKeyPrefix, Boolean useCache, String[]& searchedLocations)

at System.Web.Mvc.VirtualPathProviderViewEngine.FindView(ControllerContext controllerContext, String viewName, String masterName, Boolean useCache)

在。。。Mvc.CustomRazorViewEngine.FindView(ControllerContext controllerContext, String viewName, String masterName, Boolean useCache) in ...''Mvc''CustomRazorViewEngine.cs:line 85

在。。。Tests.MVC.ViewEngine.ViewEngineReturnsDependencyView() in ...Tests''MVC''ViewEngine.cs:line 78

我的问题是,如何创建适当的模拟来单元测试RazorViewEngine.FindView()?

单元测试自定义视图引擎

System.Web.WebPages.DisplayModeProvider.GetDisplayMode() 方法是使用 HttpContext.Items 属性,您还需要模拟该属性。

尝试:

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

,我可能迟到了,但我也有同样的问题。经过一些研究,我发现了团队测试剃须刀引擎的方式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);
}