Assertions on JsonResult

Trying to unit test a JsonResult from a .NET MVC controller method can be difficult. Many times, the Data property is populated with an anonymous object created in the Controller. This can present a problem for unit testing. Here's how to get around those problems and test the result.

Pretend that I have a controller that has an ActionMethod that constructs an anonymous object containing the aggregate result information.
[code lang="csharp"] public ActionResult GeThings()
{ List<Thing> things = ThingsQuery.GetThings(); return Json(new { status = "success", results = new { things = things } }); } [/code]

You can use dynamic objects to easily inspect the output. But first, you must designate your Unit Test assembly as a friendly assembly of the MVC assembly by adding the InternalsVisibleTo attribute to your MVC app's assembly. In the AssemblyInfo file for your MVC project add:

[code lang="csharp"] [assembly: InternalsVisibleTo("Fully.Qualified.Name.Of.Unit.Test.Assembly")] [/code]

Once this is added, types and members with internal friend scope are accessible to the friended assembly. Since anonymous objects are internal, the Unit Test framework will now have access to the anonymous object created in your controller and you can leverage the power of dynamic objects!

To test, you create a dynamic object from the Data property and then access the object properties as if they were local in scope.

[code lang="csharp"] var sut = new MyController();
var result = sut.GetThings() as JsonResult;
dynamic jsonResult = result.Data;

Assert.IsNotNull(result);
Assert.AreEqual("success", jsonResult.status);
Assert.AreEqual(12, (jsonResult.results.things as List<Thing>).Count);
[/code]

comments powered by Disqus