Как мне обернуть объект в динамический объект? - PullRequest
2 голосов
/ 01 сентября 2011

Учитывая System.Object, как получить динамический объект, с помощью которого можно получить доступ к любым его элементам.

В частности, я хочу провести модульное тестирование действия контроллера ASP.NET MVC 3, которое возвращаетJsonResult.JsonResult имеет свойство Data типа object.Я заполняю этот объект анонимным типом:

return Json(new { Success = "Success" });

В моем тесте я хочу сделать что-то вроде

var result = controller.Foo();

Assert.That(((SomeDynamicType)result.Data).Success, Is.EqualTo("Success"));

Как это сделать?

ОБНОВЛЕНИЕ
Хотя result.Data относится к типу object, проверка его в окне «Часы» показывает, что он имеет следующий тип:

{
    Name = "<>f__AnonymousType6`1" 
    FullName = "<>f__AnonymousType6`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"
} 
System.Type {System.RuntimeType}

Ответы [ 3 ]

3 голосов
/ 01 сентября 2011

Анонимные типы являются внутренними, и динамические API-интерфейсы вызываются компилятором таким образом, чтобы обеспечить защиту. Используя ImpromptuInterface, открытый исходный код, доступный в nuget, он имеет класс ImpromptuGet , который позволит вам обернуть ваш анонимный тип и будет использовать динамические API-интерфейсы, как будто из самого анонимного типа, поэтому у вас нет защиты выпуск.

//using ImpromptuInterface.Dynamic
Assert.That(ImpromptuGet.Create(result.Data).Success, Is.EqualTo("Success"));
1 голос
/ 04 июня 2013

Вы можете использовать реализацию 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");
    }
0 голосов
/ 01 сентября 2011

Поскольку вы пытаетесь проверить объект, который является Json, почему бы не запустить result.Data через JsonValueProviderFactory, а затем найти в резервном хранилище ключ с именем «Success»?

...