unit testingHtmlHelper扩展方法失败

我正在尝试测试我编写的一些HtmlHelper扩展方法。 我的第一个问题是如何创建一个HtmlHelper实例,但我使用此代码解决了这个问题:

 private static HtmlHelper CreateHtmlHelper(T model) { var viewDataDictionary = new ViewDataDictionary(model); var controllerContext = new ControllerContext(new Mock().Object, new RouteData(), new Mock().Object); var viewContext = new ViewContext(controllerContext, new Mock().Object, viewDataDictionary, new TempDataDictionary(), new Mock().Object); var mockViewDataContainer = new Mock(); mockViewDataContainer.Setup(v => v.ViewData).Returns(viewDataDictionary); return new HtmlHelper(viewContext, mockViewDataContainer.Object); } 

我的几个测试现在工作正常,但有一个测试会引发exception。 测试定义如下:

 // Arrange var inputDictionary = CreateDictionary(); var htmlHelper = CreateHtmlHelper(inputDictionary); // Act var actualHtmlString = htmlHelper.EditorFor(m => m.Dict, model).ToHtmlString(); ... 

EditorFor方法是我的扩展方法。 在该方法的某处,进行以下调用:

 tagBuilder.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(expression, metadata)); 

从我的unit testing执行此代码时,抛出以下exception:

 System.NullReferenceExceptionObject reference not set to an instance of an object. at System.Web.Mvc.ViewContext.ScopeCache.Get(IDictionary`2 scope, HttpContextBase httpContext) at System.Web.Mvc.ViewContext.get_UnobtrusiveJavaScriptEnabled() at System.Web.Mvc.HtmlHelper.GetUnobtrusiveValidationAttributes(String name, ModelMetadata metadata) at AspNetMvcDictionarySerialization.HtmlHelperExtensions.InputTagHelper(HtmlHelper htmlHelper, ModelMetadata metadata, InputType inputType, String expression, IDictionary`2 htmlAttributes, String fullName, Int32 index, String fieldType, String val) in HtmlHelperExtensions.cs: line 154 

所以代码在ScopeCache.Get失败了,但为什么呢? 有谁知道如何解决这个问题?

我最终做的是查看ASP.NET MVC的源代码 。 在他们的代码中,他们还测试HtmlHelper实例。 他们使用名为MvcHelper的实用程序类来MvcHelper ,它提供了使用正确准备的HTTP上下文创建新HtmlHelper实例的便捷方法。

删除我不需要的代码后,我最终得到了以下类:

 public static class MvcHelper { public static HtmlHelper GetHtmlHelper(TModel inputDictionary) { var viewData = new ViewDataDictionary(inputDictionary); var mockViewContext = new Mock { CallBase = true }; mockViewContext.Setup(c => c.ViewData).Returns(viewData); mockViewContext.Setup(c => c.HttpContext.Items).Returns(new Hashtable()); return new HtmlHelper(mockViewContext.Object, GetViewDataContainer(viewData)); } public static IViewDataContainer GetViewDataContainer(ViewDataDictionary viewData) { var mockContainer = new Mock(); mockContainer.Setup(c => c.ViewData).Returns(viewData); return mockContainer.Object; } } 

使用此帮助程序类,我的代码正确执行。

我已经为完整的帮助程序类创建了一个要点,以便轻松包含在您的项目中: https : //gist.github.com/ErikSchierboom/6da474dcd5751fbbc94c

看起来你可能也需要模拟HttpContext。