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.type,
"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.
data
is anobject
, so it doesn't have an indexer (data[0]
gives syntax error). correct me if im wrong, but all thatdynamic
is doing is giving late binding to the type, all we're doing here is casting anobject
to anIList<object>
, so when we enumerate over it, it's still an object. i think i'm going to have to de-serialize the object. – Timelagobj
,obj
isdynamic
- so the late binding per item still occurs. – Schaffner