Eri*_*oom 9 c# asp.net-mvc unit-testing html-helper
我正在尝试测试HtmlHelper我编写的一些扩展方法.我的第一个问题是如何创建一个HtmlHelper实例,但我使用这个代码解决了这个问题:
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);
}
Run Code Online (Sandbox Code Playgroud)
我的几个测试现在工作正常,但有一个测试会引发异常.测试定义如下:
// Arrange
var inputDictionary = CreateDictionary();
var htmlHelper = CreateHtmlHelper(inputDictionary);
// Act
var actualHtmlString = htmlHelper.EditorFor(m => m.Dict, model).ToHtmlString();
...
Run Code Online (Sandbox Code Playgroud)
该EditorFor方法是我的扩展方法.在该方法的某处,进行以下调用:
tagBuilder.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(expression, metadata));
Run Code Online (Sandbox Code Playgroud)
从我的单元测试执行此代码时,抛出以下异常:
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
Run Code Online (Sandbox Code Playgroud)
所以代码失败了ScopeCache.Get,但为什么呢?有谁知道如何解决这个问题?
Eri*_*oom 21
我最终做的是查看ASP.NET MVC的源代码.在他们的代码中,他们也测试HtmlHelper实例.他们使用名为的实用程序类来实现MvcHelper,它提供HtmlHelper了使用正确准备的HTTP上下文创建新实例的便捷方法.
删除我不需要的代码后,我最终得到了以下类:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
使用此帮助程序类,我的代码正确执行.
我已经为完整的帮助程序类创建了一个要点,以便于包含在您的项目中:https://gist.github.com/ErikSchierboom/6da474dcd5751fbbc94c
| 归档时间: |
|
| 查看次数: |
2786 次 |
| 最近记录: |