单元测试的HtmlHelper扩展方法失败 [英] Unit testing HtmlHelper extension method fails
问题描述
我想测试我已经写了一些的HtmlHelper
扩展方法。我的第一个问题是如何创建一个的HtmlHelper
实例,但我解决了使用这种code:
I am trying to test some HtmlHelper
extension methods I have written. My first problem was how to create a HtmlHelper
instance, but I solved that using this code:
private static HtmlHelper<T> CreateHtmlHelper<T>(T model)
{
var viewDataDictionary = new ViewDataDictionary(model);
var controllerContext = new ControllerContext(new Mock<HttpContextBase>().Object,
new RouteData(),
new Mock<ControllerBase>().Object);
var viewContext = new ViewContext(controllerContext, new Mock<IView>().Object, viewDataDictionary, new TempDataDictionary(), new Mock<TextWriter>().Object);
var mockViewDataContainer = new Mock<IViewDataContainer>();
mockViewDataContainer.Setup(v => v.ViewData).Returns(viewDataDictionary);
return new HtmlHelper<T>(viewContext, mockViewDataContainer.Object);
}
我的几个测试,现在工作得很好,但有一个测试抛出异常。测试定义如下:
Several of my tests now work fine, but there is one test that throws an exception. The test is defined as follows:
// Arrange
var inputDictionary = CreateDictionary();
var htmlHelper = CreateHtmlHelper(inputDictionary);
// Act
var actualHtmlString = htmlHelper.EditorFor(m => m.Dict, model).ToHtmlString();
...
的 EditorFor
方法是我的扩展方法。某处在该方法中,以下调用时:
The EditorFor
method is my extension method. Somewhere in that method, the following call is made:
tagBuilder.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(expression, metadata));
这是,当这个code是从我的单元测试执行下列异常被抛出:
It is that when this code is executed from my unit test that the following exception is thrown:
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
所以,code在 ScopeCache.Get
失败了,但是为什么呢?没有人有任何想法如何解决这个问题?
So the code fails in ScopeCache.Get
, but why? Does anyone have any idea how to solve this?
推荐答案
我最终什么了做一直在寻找在源ASP.NET MVC 的code。在他们的code,他们还测试的HtmlHelper
实例。他们这样做是使用 MvcHelper
命名的一个工具类,它提供了方便的方法来用正确的$ P创建新的的HtmlHelper
实例$ ppared HTTP上下文。
What I ended up doing was looking at the source code of ASP.NET MVC. In their code, they also test HtmlHelper
instances. They do so using a utility class named MvcHelper
, which provides convenience methods to create new HtmlHelper
instance with a correctly prepared HTTP context.
删除code,我并不需要后,我结束了以下类:
After removing the code I did not need, I ended up with the following class:
public static class MvcHelper
{
public static HtmlHelper<TModel> GetHtmlHelper<TModel>(TModel inputDictionary)
{
var viewData = new ViewDataDictionary<TModel>(inputDictionary);
var mockViewContext = new Mock<ViewContext> { CallBase = true };
mockViewContext.Setup(c => c.ViewData).Returns(viewData);
mockViewContext.Setup(c => c.HttpContext.Items).Returns(new Hashtable());
return new HtmlHelper<TModel>(mockViewContext.Object, GetViewDataContainer(viewData));
}
public static IViewDataContainer GetViewDataContainer(ViewDataDictionary viewData)
{
var mockContainer = new Mock<IViewDataContainer>();
mockContainer.Setup(c => c.ViewData).Returns(viewData);
return mockContainer.Object;
}
}
有了这个辅助类,我的code正确执行。
With this helper class, my code executed correctly.
我已经建立了完整的辅助类一个依据,以便容易纳入项目:<一href=\"https://gist.github.com/ErikSchierboom/6da474dcd5751fbbc94c\">https://gist.github.com/ErikSchierboom/6da474dcd5751fbbc94c
I have created a gist for the complete helper class to allow for easy inclusion in your project: https://gist.github.com/ErikSchierboom/6da474dcd5751fbbc94c
这篇关于单元测试的HtmlHelper扩展方法失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!