Moq и отражение, передавая динамически сгенерированное дерево выражений / лямбду в moq - PullRequest
3 голосов
/ 07 сентября 2011

Можно ли написать код, подобный следующему. Я пытаюсь использовать Moq с объектами, о которых я размышляю, как часть инфраструктуры тестирования. Приведенный ниже код вызывает исключение «Необработанный тип выражения:« Перейти »» из Moq, которое, я думаю, ожидает чего-то другого. Похоже, все должно работать!

    private void button1_Click(object sender, EventArgs e)
    {
        Ifoo  = foo Foo();

        // Create input parameter for lambda
        ParameterExpression value = Expression.Parameter(typeof(IFoo), "value");

        // create return statement for lambda
        Expression setupProperty = Expression.Return(Expression.Label(), Expression.Property(value, "Bar"), typeof(string));

        // convert expression to lambda (should now be the equivalent of "v => v.Bar")
        var func = Expression.Lambda<Func<IFoo, string>>(setupProperty, value);//.Compile();
        //string s = func(foo); // this bit works fine in .Compile() is included

        var mockFoo = new Mock<IFoo>();

        mockFoo.SetupProperty(func); // exception thrown by moq here, obviously isn't exactly the same as "v => v.Bar"
        mockFoo.Object.Bar = "Burge+";
    }

Спасибо! * * 1004

1 Ответ

4 голосов
/ 11 октября 2011

Хорошо, это возможно, вот исправленный код.

// Create input parameter for lambda 
ParameterExpression value = Expression.Parameter(typeof(IFoo), "value"); 

// create return statement for lambda 
Expression setupProperty = Expression.Property(value, "Bar"); 

// convert expression to lambda (should now be the equivalent of "v => v.Bar") 
var func = Expression.Lambda<Func<IFoo, string>>(setupProperty, value);

var mockFoo = new Mock<IFoo>(); 
mockFoo.SetupProperty(func); // this works now
mockFoo.Object.Bar = "Burge+"; 

Я исследовал это, создав выражение из лямбды, используя код ниже

Expression<Func<IFoo, string>> setupBar = v => c.Bar;

Затем я посмотрелэто в отладчике vs 2010. У выражений есть «представление отладки», которое показывает текстовое представление выражения, так что можно добавить часы на это или что-то подобное.Вышеприведенное выглядит как

 .Lambda #Lambda1<System.Func`2[WindowsFormsApplication1.IFoo,System.String]>(WindowsFormsApplication1.IFoo
 $v) {
   $v.Bar
 }

Я посмотрел на это и попытался выяснить, что Expressions сделает это, затем создал выражение и сравнил его в отладчике.

Интересная вещь дляЯ в том, что хотя это выражение возвращает значение, нет оператора присваивания или возврата.Я думаю, это должно быть как-то неявно.

...