Module Testing HtmlHelper Extension Method Does Not Work

I am trying to check out some of the HtmlHelper extension methods that I wrote. My first problem was how to create an instance of HtmlHelper , but I decided 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(); ... 

The EditorFor method is my extension method. Somewhere in this method, the following call is made:

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

This is that when this code is executed from my unit test, 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 

Thus, the code does not work in ScopeCache.Get , but why? Does anyone know how to solve this?

+8
c # unit-testing asp.net-mvc html-helper
Aug 08 '14 at 15:03
source share
2 answers

What I ended up looking at is the source code for ASP.NET MVC . In their code, they also validate instances of HtmlHelper . They do this with a utility class called MvcHelper , which provides convenient methods for creating a new HtmlHelper instance with a properly prepared HTTP context.

After removing the code, I didn’t need it, 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; } } 

With this helper class, my code runs correctly.

I created gist for a complete helper class that makes it easy to include in your project: https://gist.github.com/ErikSchierboom/6da474dcd5751fbbc94c

+20
Aug 09 '14 at 8:38
source share
— -

It sounds like you need to make fun of the HttpContext too.

+1
Aug 08 '14 at 16:11
source share



All Articles