Quantcast
Channel: try-catch-FAIL - .NET
Viewing all articles
Browse latest Browse all 14

Simplified unit testing for ASP.NET MVC JsonResult

$
0
0

There are quitea fewexamples floating around on the web that describe how to test your JsonResult objects to make sure the data was correctly packaged.  They all follow the same basic pattern: mock out core ASP.NET objects (such as ControllerContext, HttpResponse, and HttpContext), call JsonResult.ExecuteResult, recover what was written to HttpResponse.Output, and deserialize it.  Sure, this approach works, but in the same manner as cleaning your house out by lighting it on fire.  It’s way overkill.  There’s a much easier way.  For simple objects, just cast JsonResult.Data:

   1:string value = "Hello, there!";
   2:  
   3: JsonResult result = new JsonResult { Data=value };
   4:  
   5://SURPRISE!
   6: Assert.AreEqual(value, (string)result.Data);

Yeah, that seems fairly obvious.  You don’t even need the explicit cast there, I just threw it in to prove the point.  But what about anonymous types?  Easy:

   1:var value = new { Id=5, Something="Else" };
   2:  
   3: JsonResult result = new JsonResult { Data=value };
   4:  
   5: IDictionary<string,object> data = new RouteValueDictionary(result.Data);
   6:  
   7: Assert.AreEqual(5, data["Id"]);
   8: Assert.AreEqual("Else", data["Something"]);

See, easy! “But what about arrays of anonymous types?!?!?” Do not fret, LINQ to the rescue:

   1:var values = new[]
   2:                  {
   3:new { Id = 5, Something = "Else" },
   4:new { Id = 6, Something = "New" },
   5:new { Id = 7, Something = "Old" },
   6:                  };
   7:  
   8: JsonResult result = new JsonResult { Data = values };
   9:  
  10: IDictionary<string, object>[] data = ((object[]) result.Data).Select(o => new RouteValueDictionary(o)).ToArray();
  11:  
  12: Assert.AreEqual(5, data[0]["Id"]);
  13: Assert.AreEqual(6, data[1]["Id"]);
  14: Assert.AreEqual(7, data[2]["Id"]);
  15: Assert.AreEqual("Else", data[0]["Something"]);
  16: Assert.AreEqual("New", data[1]["Something"]);
  17: Assert.AreEqual("Old", data[2]["Something"]);

Again, easy!

Alright, I know what you’re thinking.  “But Matt, the other solutions are all way more complicated, plus you’re cheating, that isn’t what JsonResult.ExecuteResult is going to do!” Well, you’re half-right, the other solutions are way more complicated, but this is actually simulating precisely what ExecuteResult will do.  Don’t believe me?  Pop it open in Reflector, or just browse the source (man I love Subversion).  It isn’t doing anything magical, it’s just using JavaScriptSerializer.  My solution just cuts out the middle man and doesn’t require you to mock out a bunch of complicated objects.


Viewing all articles
Browse latest Browse all 14

Trending Articles