Asserting JsonResult Containing Anonymous Type

前端 未结 3 461
广开言路
广开言路 2021-02-05 00:51

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          


        
相关标签:
3条回答
  • 2021-02-05 01:19

    Having read the responses here and then looking further afield I found a 2009 msdn blog post with a different approach again. But.. in the comments was a very simple and very elegant solution by Kieran ... to use .ToString().

    In your original case:

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

    You could test by doing:

    var jsonResult = controller.Test();
    Assert.AreEqual("{Id = 123}", jsonResult.Data.ToString());
    

    I much prefer this solution as it:

    • avoids changing the original code (InternalsVisibleTo, ExpandoObject),
    • avoids using MvcContrib and RhinoMocks (no issue with either of these but why add just to be able to test JsonResult?), and,
    • avoids using Reflection (adds complexity to the tests).
    0 讨论(0)
  • 2021-02-05 01:32

    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));
    
    0 讨论(0)
  • 2021-02-05 01:42

    Anonymous types are internal, so you can't expose them to another library, the one with tests. If you placed testing code in the same library as controller, it will work.

    0 讨论(0)
提交回复
热议问题