Hi Guys,
If i have a controller like this:
[HttpPost]
public JsonResult FindStuff(string query)
{
var results = _repo.GetStuff(query);
var jsonResult = results.Select(x => new
{
id = x.Id,
name = x.Foo,
type = x.Bar
}).ToList();
return Json(jsonResult);
}
Basically, i grab stuff from my repository, then project it into a List<T> of anonymous types.
How can i unit-test it?
System.Web.Mvc.JsonResult has a property called Data, but it's of type object, as we expected.
So - does that mean if i want to test that the JSON object has the properties i expect ("id", "name", "type"), i have to use reflection?
EDIT:
Here's my test:
// Arrange.
const string autoCompleteQuery = "soho";
// Act.
var actionResult = _controller.FindLocations(autoCompleteQuery);
// Assert.
Assert.IsNotNull(actionResult, "No ActionResult returned from action method.");
dynamic jsonCollection = actionResult.Data;
foreach (dynamic json in jsonCollection)
{
Assert.IsNotNull(json.id, "JSON record does not contain \"id\" required property.");
Assert.IsNotNull(json.name, "JSON record does not contain \"name\" required property.");
Assert.IsNotNull(json.typee, "JSON record does not contain \"type\" required property.");
}
But i get a runtime error in the loop, stating "object does not contain a definition for id".
When i breakpoint, actionResult.Data is defined as a List<T> of anonymous types, so i figure if i enumerate through these, i can check the properties. Inside the loop, the object does have a property called "id" - so not sure what the issue is.
RPM, you look to be correct. I still have much to learn about dynamic and I cannot get Marc's approach to work either. So here is how I was doing it before. You may find it helpful. I just wrote a simple extension method:
public static object GetReflectedProperty(this object obj, string propertyName)
{
obj.ThrowIfNull("obj");
propertyName.ThrowIfNull("propertyName");
PropertyInfo property = obj.GetType().GetProperty(propertyName);
if (property == null)
{
return null;
}
return property.GetValue(obj, null);
}
Then I just use that to do assertions on my Json data:
JsonResult result = controller.MyAction(...);
...
Assert.That(result.Data, Is.Not.Null, "There should be some data for the JsonResult");
Assert.That(result.Data.GetReflectedProperty("page"), Is.EqualTo(page));