简体   繁体   English

Moq和反射,将动态生成的表达式树/ lambda传递给moq

[英]Moq and reflection, passing dynamically generated expression tree / lambda to moq

Is it possible to write code like the following. 是否可以编写如下代码。 I'm trying to using Moq with objects that I'm reflecting on as part of a testing framework. 我正在尝试将Moq与我正在反思的对象一起用作测试框架的一部分。 The code below raises a "Unhandled expression type: 'Goto'" exception from Moq, which I guess is expecting something different. 下面的代码从Moq引发了一个“Unhandled expression type:'Goto'”异常,我猜这个异常会有所不同。 It kind of looks like it should work though! 看起来它应该工作了!

    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+";
    }

Thanks! 谢谢!

Ok, this is possible, here is the corrected code. 好的,这是可能的,这是更正后的代码。

// 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+"; 

I investigated this by creating an expression from a lambda using the code below 我通过使用下面的代码从lambda创建表达式来调查这一点

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

I then looked at this in the debugger in vs 2010. Expressions have a "Debug View" that shows a text representation of the expression so it is possible to add a watch on that or something similar. 然后我在vs 2010中的调试器中查看了这个。表达式有一个“调试视图”,它显示了表达式的文本表示,因此可以在该类或类似的东西上添加监视。 The above comes out as 以上是出自

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

I looked at this and tried to work out what Expressions would make this, then created an expression and compared it in the debugger. 我查看了这个并试图找出表达式会做什么,然后创建一个表达式并在调试器中进行比较。

The interesting thing for me is that although this expression returns a value there is no assignment or return statement. 对我来说有趣的是,虽然这个表达式返回一个值,但是没有赋值或返回语句。 I guess this must be implicit somehow. 我猜这必须以某种方式隐含。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM