Unit Testing Html Helpers for ASP.NET MVC
Html helpers for ASP.NET MVC are static extension methods, which frequently reference the
I've added just enough code here to get the prototype to compile. Now let's write some unit tests. First we need to validate the arguments. I'm using MSTest here:
Note that I have elected to call this method as a regular static method rather than as an extension method. Either one is valid, but since I am unit testing the case where the
Those tests will fail when run, so I'll write some code to fix that:
Now let's presume that the requirements of the new method specify that the table should get its HTML
I elected to only implement the
With these two, small classes, I can write a test for the helper which will execute without throwing any exceptions. Well, except for the fact that the assertion fails:
I needed the
Finally, I can implement the helper to make this unit test pass:
ViewContext
and HttpContext
. Combined, this can make unit testing a bit tricky. Let's write a new Html helper using a test-first methodology. Let's start with a prototype function:
public static MvcHtmlString MyTable(this HtmlHelper helper, MyModel model, IDictionary<string, object> htmlAttributes)
{
return MvcHtmlString.Empty;
}
I've added just enough code here to get the prototype to compile. Now let's write some unit tests. First we need to validate the arguments. I'm using MSTest here:
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void MyTable_should_throw_when_helper_argument_null()
{
var model = new MyModel();
MyHelpers.MyTable(null, model, null);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void MyTable_should_throw_when_model_argument_null()
{
var hh = new HtmlHelper(null, null);
MyHelpers.MyTable(hh, null, null);
}
Note that I have elected to call this method as a regular static method rather than as an extension method. Either one is valid, but since I am unit testing the case where the
HtmlHelper
argument is null
, it makes more sense to call the method under test as a regular static method.Those tests will fail when run, so I'll write some code to fix that:
public static MvcHtmlString MyTable(this HtmlHelper helper, MyModel model, IDictionary<string, object> htmlAttributes)
{
if (helper == null)
{
throw new ArgumentNullException("helper");
}
if (model == null)
{
throw new ArgumentNullException("model");
}
return MvcHtmlString.Empty;
}
Now let's presume that the requirements of the new method specify that the table should get its HTML
id
from the HttpContext.Items
. This is of course a very stupid place to store an HTML id
, but I want to demonstrate how to fake the HttpContext
, since that is something that people often find difficult. So let's make a fake HttpContext
. I'll need a lightweight implementation of IViewDataContainer
, as well, for reasons which will be clear later on:
private class FakeHttpContext : HttpContextBase
{
private Dictionary<object, object> _items = new Dictionary<object, object>();
public override IDictionary Items { get { return _items; } }
}
private class FakeViewDataContainer : IViewDataContainer
{
private ViewDataDictionary _viewData = new ViewDataDictionary();
public ViewDataDictionary ViewData { get { return _viewData; } set { _viewData = value; } }
}
I elected to only implement the
Items
property of HttpContextBase
, since that is the only one I'll need to reference in the implementation of my helper. Were I to reference other HttpContextBase
properties which I did not override, I would expect to see a NotImplementedException
at runtime.With these two, small classes, I can write a test for the helper which will execute without throwing any exceptions. Well, except for the fact that the assertion fails:
[TestMethod]
public void MyTable_should_render_HTML_table_with_id_from_http_context()
{
var vc = new ViewContext();
vc.HttpContext = new FakeHttpContext();
vc.HttpContext.Items.Add(MyHelpers.IdKey, "foo");
var hh = new HtmlHelper(vc, new FakeViewDataContainer());
var model = new MyModel();
var result = MyHelpers.MyTable(hh, model, null).ToString();
Assert.AreEqual("<table id = \"foo\"></table>", result);
}
I needed the
IViewDataContainer
because the two argument constructor for HtmlHelper
will throw ArgumentNullException
if you pass a null
for the second argument.Finally, I can implement the helper to make this unit test pass:
public static MvcHtmlString MyTable(this HtmlHelper helper, MyModel model, IDictionary<string, object> htmlAttributes)
MyHelpers.IdKey]);
{
if (helper == null)
{
throw new ArgumentNullException("helper");
}
if (model == null)
{
throw new ArgumentNullException("model");
}
TagBuilder tagBuilder = new TagBuilder("table");
tagBuilder.MergeAttributes(htmlAttributes);
tagBuilder.GenerateId(helper.ViewContext.HttpContext.Items[
return MvcHtmlString.Create(tagBuilder.ToString(TagRenderMode.Normal));
}

Comments
-
Please login first in order for you to submit comments
- Page :
- 1
Can you program a puzzle like the one at acrostics.org ? I need such a program and am seeking a programmer who will work with/for me.