Unit testing ActionResults is fairly easy yet JsonResults can pose a problem. I’ve seen a few ways to do this and they just seemed like “too much” to me. So here’s a way that I’ve devised that works very well. Its sort of has a “hack” feel to it, but it works perfectly.
Controller Action:
public JsonResult AddContent(string content, string contentName)
{
var isExistingContent = false;
var wasAdded = false;
if (_service.IsNewContent(contentName))
{
_service.AddNewContent(content, contentName);
isExistingContent = false;
wasAdded = true;
}
// do some other logic, etc
return Json(new {isExisting = isExistingContent, added = wasAdded});
}
If you want to test the JsonResult that is coming back then we need a way to grab it. Since its an anonymous type it makes things a bit more tricky.
Here’s how to test it:
[Test]
public void The_controller_should_be_able_to_add_new_content()
{
// Arrange
_mockService.Expect(x => x.IsNewContent("foo")).Return(false);
_mockService.Expect(x => x.AddNewContent("blah", "fooey")).IgnoreArguments();
// Act
var result = _controller.AddContent("fresh data", "foo");
// Assert
var wrapper = new System.Web.Routing.RouteValueDictionary(result.Data); // Magic black box
Assert.That(wrapper["isExisting"], Is.False);
Assert.That(wrapper["added"], Is.True);
}
We can cast the anon type to a RouteValueDictionary and then test off of the keys. Blammo. Simple.