模拟库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
不是?
答案 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
作为局部变量的测试项目,它与string
和object
一起正常运行。如果我错过了什么,请检查我的配置。 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; }
}