给定System.Object
,我如何获得一个动态对象来访问它可能拥有的任何成员。
具体来说,我想对一个返回JsonResult
的ASP.NET MVC 3控制器动作进行单元测试。 JsonResult
的{{1}}属性类型为Data
。我用匿名类型填充此对象:
object
在我的测试中,我想做类似
的事情return Json(new { Success = "Success" });
这是怎么做到的?
更新
虽然var result = controller.Foo();
Assert.That(((SomeDynamicType)result.Data).Success, Is.EqualTo("Success"));
的类型为result.Data
,但在“监视”窗口中检查它会显示它具有以下类型:
object
答案 0 :(得分:3)
匿名类型是内部的,动态api由编译器以尊重该保护的方式调用。使用ImpromptInInface,在nuget中可用的开源,它有一个ImpromptuGet类,允许你包装你的匿名类型,并将使用动态api,就好像来自匿名类型本身,所以你没有保护问题。
//using ImpromptuInterface.Dynamic
Assert.That(ImpromptuGet.Create(result.Data).Success, Is.EqualTo("Success"));
答案 1 :(得分:1)
您可以使用DynamicObject
的实现:
public class MyDynamic: DynamicObject
{
private readonly Dictionary<string, object> dictionary = new Dictionary<string, object>();
public MyDynamic(object initialData)
{
if (initialData == null) throw new ArgumentNullException("initialData");
var type = initialData.GetType();
foreach (var propertyInfo in type.GetProperties())
{
dictionary.Add(propertyInfo.Name, propertyInfo.GetValue(initialData, null));
}
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
dictionary.TryGetValue(binder.Name, out result);
return true;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
dictionary[binder.Name] = value;
return true;
}
}
然后:
public void MyTest()
{
var json = new {Success = "Ok"};
dynamic dynObj = new MyDynamic(json);
Assert.AreEqual(dynObj.Success, "Ok");
}
答案 2 :(得分:-1)
由于您正在尝试检查Json的对象,为什么不通过JsonValueProviderFactory运行result.Data,然后在后备存储中搜索名为“Success”的键?