【发布时间】:2011-06-26 17:51:50
【问题描述】:
如果我有这样的控制器:
[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);
}
基本上,我从存储库中获取内容,然后将其投影到匿名类型的 List<T> 中。
如何对它进行单元测试?
System.Web.Mvc.JsonResult 有一个名为 Data 的属性,但正如我们所料,它的类型是 object。
这是否意味着如果我想测试 JSON 对象是否具有我期望的属性(“id”、“name”、“type”),我必须使用反射?
编辑:
这是我的测试:
// 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.");
}
但我在循环中遇到运行时错误,指出“对象不包含 id 的定义”。
当我断点时,actionResult.Data 被定义为匿名类型的List<T>,所以我想如果我枚举这些,我可以检查属性。在循环内部,对象确实有一个名为“id”的属性 - 所以不确定是什么问题。
【问题讨论】:
-
重新编辑 - 你可以尝试类似 var items = (IEnumerable)actionResult.Data; foreach(项目中的动态 obj){...}
-
我在这里用`var list = (IList)data; Assert.AreEqual(list.Count, 2);动态 obj = 数据[0];断言.AreEqual(obj.id, 12); Assert.AreEqual(obj.name, "Fred"); Assert.AreEqual(obj.type, 'a');对象=数据[1];断言.AreEqual(obj.id,14); Assert.AreEqual(obj.name, "Jim"); Assert.AreEqual(obj.type, 'c'); foreach (动态 d in list) { if (d.id == null) throw new InvalidOperationException(); }` 看起来还不错……
-
明天我到办公室时让我试试那个代码。干杯。
-
@RPM1984 在提取到
obj时,obj是dynamic- 所以后期绑定 per item 仍然会发生。 -
@RPM - 没问题;我很高兴你有一个可行的解决方案
标签: c# asp.net-mvc json unit-testing jsonresult