表达<FUNC <>&GT;只有有效的内联而不是Moq的Setup()中的绑定lambda?</func <>

时间:2013-01-15 21:59:45

标签: c# recursion lambda moq expression-trees

模拟库Moq有一个带有签名的Setup()方法:

public ISetup<T, TResult> Setup<TResult>(Expression<Func<T, TResult>> expression)

所以我可以做这样的事情(使用库的递归模拟):

Mock<Thing> _thing = new Mock<Thing>();
_thing.Setup((Thing t) => t.PropA.SubPropB).Returns(string.Empty);

但这失败了:

Expression<Func<Thing, object>> test = (Thing t) => t.PropA.SubPropB;
_thing.Setup(test).Returns(string.Empty);

错误:

Expression is not a method invocation: t => (Object)t.PropA.SubPropB

内联lambda和首先分配给变量的lambda有什么区别?是不是表达式树并且尚未编译(Moq解析树)?

编辑 - 看起来问题在于Func<Thing, object>输入。为什么,例如,string可以接受,但object不是?

1 个答案:

答案 0 :(得分:1)

  

为什么,例如,字符串可以接受,但对象不是?

因为moq中的函数声明不是泛型类型的协变。尝试以下一种方式设置moq

 _thing.Setup(test).Returns((object)string.Empty);

因为您有下一个签名Expression<Func<Thing, object>>,而且与object无法协调

或者将您的签名更改为此string(假设t.PropA.SubPropB返回字符串):

Expression<Func<Thing, string>> test = (Thing t) => t.PropA.SubPropB;
                        //^here should be string

<强>实时情况下 我创建了一个以Expression作为局部变量的测试项目,它与stringobject一起正常运行。如果我错过了什么,请检查我的配置。 Moq - 4.0.10827v

[TestFixture]
public class Class1
{
    [Test]
    public void TestMethod()
    {
        Mock<Thing> _thing = new Mock<Thing>();

        Expression<Func<Thing, string>> setup = t => t.PropA.SubPropB;
//                               ^ works with string and object
        _thing.Setup(setup).Returns(string.Empty);

        Assert.IsEmpty(_thing.Object.PropA.SubPropB);

    }
}

public class Thing
{
    public virtual Thingy PropA { get; set; }
}

public class Thingy
{
    public virtual string SubPropB { get; set; }
}