0

像这样的课

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

函数 XF 使用 TT 做某事。我什么测试 F 。

所以

[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 设置为非虚拟时,它就通过了。

那么,为什么会这样呢?以及如何使虚拟属性可以写入?

4

2 回答 2

2

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

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

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

您还可以让 Moq 使用以下方法设置您的所有属性:

t.SetupAllProperties();

在这里可以找到很多有用的示例:http ://code.google.com/p/moq/wiki/QuickStart

于 2012-10-10T03:45:26.370 回答
2

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

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

如果在 mock 上将 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() 更好的答案,但在人们只想将设置用于某些功能的情况下非常有用。

于 2012-10-10T07:57:58.627 回答