【问题标题】:What is the best way to unit test a simple JsonResult?对简单 JsonResult 进行单元测试的最佳方法是什么?
【发布时间】:2011-11-11 03:04:16
【问题描述】:

如果 AJAX 调用成功,我想返回一个带有 Success = true 的简单对象

public ActionResult Foo(int id)
{
    // ...
    return Json(new {Success=true});
}

这很好用,我的 javascript 接收到的对象看起来像

{ Success : true }  

但是因为返回的对象是匿名类型,所以我不能在我的测试中执行(类似的)以下操作:

var result = (JsonResult)controller.AddNote(id, message);
dynamic data = result.Data;

// Assert
Assert.That(data.Success, Is.EqualTo(true));

所以我尝试返回一个 ExpandoObject,它允许测试以我想要的方式工作,但在 AJAX 响应中发回的 JSON 是一团糟,as detailed in this question

[{"Key":"Success","Value":true}]

是否有一种简单、干净的方法来实现看起来应该很容易的事情,或者是像链接问题中那样实现一些自定义序列化的唯一方法?

【问题讨论】:

  • 您在单元测试中获得的 result.Data 不能包含 json 数据,因为 jsonResult 序列化程序仅在单元测试中不运行的 ExecuteResult 方法中运行。 result.Data 中的“数据”只是您在 AddNote/Foo 操作中分配的匿名数据。你测试的不是json数据!

标签: asp.net-mvc-3 dynamic expandoobject


【解决方案1】:
  1. 如果您使用[assembly: InternalsVisibleTo("TestsProject")] 标记您的控制器组件,则可以使用dynamic 获取值。因为为匿名类型生成的类是内部的,并且运行时绑定不适用于内部类型。在这个article 中,您可以找到有关此的更多信息。
  2. 如果您不喜欢这种方法,您可以回退到普通的旧反射(隐藏在一些辅助方法后面):

    [TestMethod]
    public void AddNote1()
    {
        ...
        var result = ((JsonResult)controller.AddNote(id, message));
        var data = result.Data;
    
        // Assert
        Assert.AreEqual(Get<bool>(data, "Success"), true);
     }
    
     private T Get<T>(object instance, string propertyName)
     {
         return (T) instance.GetType().GetProperty(propertyName).GetValue(instance, null);
     }
    
  3. 使用命名类而不是匿名类。

  4. 您必须使用您提到的某种序列化解决方法。

【讨论】:

  • InternalsVisibleTo 传奇!
【解决方案2】:

你可以做的是:

var js = new JavaScriptSerializer();
var response = new { id = 0, Status = false };
dynamic object = js.Deserialize(new StringReader(JSONText), response.GetType());

Assert.IsTrue(object.Success)

这是做什么的:

  1. 创建一个 JavaScriptSerializer。
  2. 创建一个与您的 json 布局相同的新匿名对象,以便序列化程序知道您的对象是什么样的
  3. 将 json 反序列化为新的动态对象。

这样做的缺点是您的 json 对象上没有 IntelliSense,因此编译器不会捕获任何拼写错误。

注意:我这里的代码是在 stackoverflow 中写的,所以可能会有一些小错误。我没有测试它,但它应该可以工作:P

【讨论】:

  • 你从哪里得到JSONText?在单元测试中,您没有通过网络传输的实际 HTTP 正文...
猜你喜欢
  • 2019-02-12
  • 2010-09-07
  • 1970-01-01
  • 1970-01-01
  • 2011-06-06
  • 2010-09-27
  • 2010-09-05
  • 2011-02-24
相关资源
最近更新 更多