Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"dynamic" keyword and JSON data

An action method in my ASP.NET MVC2 application returns a JsonResult object and in my unit test I would like to check that the returned JSON object indeed contains the expected values.

I tried this:

1. dynamic json = ((JsonResult)myActionResult).Data;
2. Assert.AreEqual(JsonMessagesHelper.ErrorLevel.ERROR.ToString(), json.ErrorLevel);

But I get a RuntimeBinderException "'object' does not contain a definition for 'ErrorLevel'".

However, when I place a breakpoint on line 2 and inspect the json dynamic variable (see picture below), it obviously does contain the ErrorLevel string and it has the expected value, so if the runtime binder wasn't playing funny the test would pass.

Snapshot of the Locals debugger window

What am I not getting? What am I doing wrong and how can I fix this? How can I make the assertion pass?

like image 693
Peter Perháč Avatar asked Jan 06 '11 11:01

Peter Perháč


2 Answers

You don't really need dynamic. Here's an example. Suppose you had the following action which you would like to unit test:

public ActionResult Index()
{
    return Json(new { Id = 5, Foo = "bar" });
}

and the corresponding test:

// act
var actual = subjectUnderTest.Index();

// assert
var data = new RouteValueDictionary(actual.Data);
Assert.AreEqual(5, data["Id"]);
Assert.AreEqual("bar", data["Foo"]);

Also you might find the following blog post useful.

like image 85
Darin Dimitrov Avatar answered Oct 14 '22 22:10

Darin Dimitrov


The Data property of the JsonResult is of type Object this means, although you have a dynamic declaration, the type that is set is still Object. The other issue is that you are using an anonymous type as the Data and then trying to access that as a declared instance outside of its applicable scope. Use @Darin's technique for accessing the property values using a RouteValueDictionary.

like image 25
Matthew Abbott Avatar answered Oct 14 '22 23:10

Matthew Abbott