Skip to content

Returning JsonResult From ASP.NET MVC 2.0 Controller and Unit Testing

Updated: at 11:18 PM

* I’m adding this comment after the post has been written to let anyone coming here know of another great post that goes further to explain no only what I’ve done here, but also two other ways including Mock and using Json Serialization.  The Post is written by Ashic Mahtab, aka “HeartattacK” on the forums.  His well written and informative article is here:  ASP.NET MVC – Unit Testing JsonResult Returning Anonymous Types.

This post will show how to return a simple Json result from an ASP.NET MVC 2.0 web project.  It will show how to test that result inside a unit test and essentially pick apart the Json, just like a JavaScript (or other client) would do.  It seems like it should be very simple (and indeed, once you see the answer it is), however there are lots of length discussions on the forums about this with all kinds of positives and negatives.  The one I based my solution on is from Stack Overflow and is here..  My personal length discussion that did not really yield a satisfactory answer is here.

If you follow my method, you’ll be able to unit test a JsonResult created by an MVC asp.net web application.


Controller Side (Server)

Let’s get started. First thing we need to do is have a controller that return a JsonResult.  Below is the one I’m currently working on.  Let me show the code, then explain it.

 

public ActionResult Get(FormCollection form)
{
var query = new FolderPairQuery();
if (form["query"] != null)
{
query = form["query"].FromJson<FolderPairQuery>();
}

if (form["start"] != null && form["limit"] != null)
{
query.Start = Convert.ToInt32(form["start"]);
query.Limit = Convert.ToInt32(form["limit"]);
}

var results = FolderPairManager.I.Get(query);
return Json(new
{
success = true,
rows = results,
total = query.OutputTotal
}, JsonRequestBehavior.AllowGet);
}
 

This code is actually part of the file FolderPairController.cs.  It returns an ActionResult (which in this case is JsonResult that derives from ActionResult).  All the way to the return statement is just stuff that I do in my code to pull apart the passed in Request variables and process them.  I only leave them in for context.  It does not matter how you get your “results” and “total”, it just matters that you do. Then, the return statement is the part that is of interest.  It’s basically returning an anonymous class which is actually a JsonResult.  In System.Web.Mvc.Controller.cs, you will see that Json is defined as:

 

protected internal JsonResult Json(object data, JsonRequestBehavior behavior);
 
 
The first parameter is “object data” which means it can be anything, and in our case, it is an anonymous object.
 

Unit Test Side (Client)

 
So now, let’s take a look at the unit test itself.  Again, let me show the code, then explain it.
 
[TestMethod]
public void InsertControllerTest()
{
var pairName = string.Format("FolderPair {0}",
(new Random().Next(1, 10000)));
var folderPairResults =
new List<FolderPairResult>()
{
new FolderPairResult
{
ActionTypeId = 1,
CheckFileContent = true,
ActiveForRunAll = true,
ExcludeHiddenFiles = true,
ExcludeReadOnly = true,
ExcludeSystemFiles = true,
FolderPairName = pairName,
LeftFolder = "left",
RightFolder = "right",
SaveOverWrittenRecycleBin = true,
UsersId = 1
}
};



string jsonInsert = JsonConvert.SerializeObject(folderPairResults);

var form =
new FormCollection
{
{"data", jsonInsert}
};


using (var controller = new FolderPairController())
{

controller.Insert(form);
}

// verify it got inserted.
var queryObj = new FolderPairQuery { FolderPairName = pairName };
string json = JsonConvert.SerializeObject(queryObj);
var formGet =
new FormCollection()
{
{"query", json}
};

using (var controller = new FolderPairController())
{
var jsonResult1 = controller.Get(formGet) as JsonResult;
Assert.IsNotNull(jsonResult1,"jsonResult1 is null which is bad");


List<FolderPairResult> folderPairResults1 =
(List<FolderPairResult>)
(jsonResult1.Data.GetType().GetProperty("rows")).GetValue(jsonResult1.Data, null);
bool success =
(bool)
(jsonResult1.Data.GetType().GetProperty("success")).GetValue(jsonResult1.Data, null);
int total =
(int)
(jsonResult1.Data.GetType().GetProperty("total")).GetValue(jsonResult1.Data, null);

Assert.IsTrue(folderPairResults1.Count == 1, "Not one item returned");
Assert.IsTrue(folderPairResults1[0].FolderPairName.Equals(pairName),
"Wrong pairname returned");
}
}

Up to the line “// verify it got inserted”, we simply are adding the record to the database in our unit test.  I won’t go into detail about that in this post since it is not really the purpose here.  I’m really just trying to show how to extract from the JsonResult the values that are returned from the server.
 
So, notice the line “var jsonResult1 = controller.Get(formGet) as JsonResult;”.  This line simply calls the controller’s get method with the appropriate query parameters and returns us a JsonResult.  Now, let’s look at how to get the data out of that.  It’s really quite simple using reflection.  Each of the following three lines pulls the data out so that at the end, we have our typed data for rows,total and count.
 
Hopefully, this will help you.  Like I said in the beginning, there are lots of ways to do this.  This just shows one that works for me.