4

模拟库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不能接受?

4

1 回答 1

3

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

因为函数声明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局部变量的测试项目,它与stringand一起工作正常object。如果我遗漏了什么,请检查我的配置。最小起订量 - 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; }
}
于 2013-01-15T22:00:59.933 回答