Moq - 具有虚拟属性的对象无法在外部写入

时间:2012-10-10 03:28:31

标签: virtual moq

像这样的课程

public abstract class TT
{
    public virtual int ID { get; set; }
}
public class X
{
    public void F(TT t)
    {
        t.ID = 100;
    }
}

函数X.F使用TT做某事。 我测试的是什么。

所以

[TestMethod]
public void T()
{
    var t = new Mock<TT>();
    new X().F(t.Object);
    Assert.AreEqual(100, t.Object.ID);
}

但是t.Object.ID始终为“0”。 当我将ID设置为非虚拟时,它就会被传递。

所以,为什么呢?如何才能使虚拟财产被编入?

2 个答案:

答案 0 :(得分:2)

问题在于Moq如何实际构建模拟。因为在这种情况下,它通过扩展您的类和覆盖来实现它,标记为虚拟的属性将由Moq处理。

所以我相信你的实现中缺少的是属性的设置:

t.SetupProperty(f => f.ID);

您还可以使用Moq设置所有属性:

t.SetupAllProperties();

可在此处找到许多有用的示例:http://code.google.com/p/moq/wiki/QuickStart

答案 1 :(得分:2)

因为TT是一个具有虚方法(而不是接口)的类,所以这是另一种选择。

正如Pablo的回答中提到的,Moq扩展了你的课程,超越了虚拟财产。但是,有一个选项 CallBase ,它告诉Moq使用原始(被覆盖的)版本,其中没有定义设置。

如果在模拟上将CallBase设置为true,则将调用原始属性,并且不需要显式设置该属性。

[TestMethod]
public void T() {
    var t = new Mock<TT>() { CallBase = true };
    new X().F(t.Object);
    Assert.AreEqual(100, t.Object.ID);
}

这不是比使用SetupUpAllProperties()更好的答案,但在想要仅使用某些功能的设置的情况下非常有用。