Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
242 views
in Technique[技术] by (71.8m points)

c# - Asserting JsonResult Containing Anonymous Type

I was trying to unit test a method in one of my Controllers returning a JsonResult. To my surprise the following code didn't work:

[HttpPost]
public JsonResult Test() {
    return Json(new {Id = 123});
}

This is how I test it (also note that the test code resides in another assembly):

// Act
dynamic jsonResult = testController.Test().Data;

// Assert
Assert.AreEqual(123, jsonResult.Id);

The Assert throws an exception:

'object' does not contain a definition for 'Id'

I've since resolved it by using the following:

[HttpPost]
public JsonResult Test() {
   dynamic data = new ExpandoObject();
   data.Id = 123;
   return Json(data);
}

I'm trying to understand why isn't the first one working ? It also seems to be working with basically anything BUT an anonymous type.

question from:https://stackoverflow.com/questions/16876144/asserting-jsonresult-containing-anonymous-type

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

To be clear, the specific problem you are encountering is that C# dynamic does not work with non-public members. This is by design, presumably to discourage that sort of thing. Since as LukLed stated, anonymous types are public only within the same assembly (or to be more precise, anonymous types are simply marked internal, not public), you are running into this barrier.

Probably the cleanest solution would be for you to use InternalsVisibleTo. It allows you to name another assembly that can access its non-public members. Using it for tests is one of the primary reasons for its existance. In your example, you would place in your primary project's AssemblyInfo.cs the following line:

[assembly: InternalsVisibleTo("AssemblyNameOfYourTestProject")]

Once you do that, the error will go away (I just tried it myself).

Alternatively, you could have just used brute force reflection:

Assert.AreEqual(123, jsonResult.GetType().GetProperty("Id").GetValue(jsonResult, null));

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...