【问题标题】:Moq: Setup a property without setter?起订量:在没有设置器的情况下设置属性?
【发布时间】:2011-05-01 14:54:21
【问题描述】:

我有以下课程:

public class PairOfDice
{
    private Dice d1,d2;
    public int Value 
    {
       get { return d1.Value + d2.Value; }
    }
}

现在我想在我的测试中使用PairOfDice,它返回值 1,尽管我在我的真实骰子中使用随机值:

[Test]
public void DoOneStep ()
{
    var mock = new Mock<PairOfDice>();
    mock.Setup(x => x.Value).Return(2);
    PairOfDice d = mock.Object;
    Assert.AreEqual(1, d.Value);
}

不幸的是,我收到了 Invalid setup on non-overridable member 错误。在这种情况下我能做什么?

请注意,这是我第一次尝试实施单元测试。

【问题讨论】:

    标签: c# unit-testing properties moq


    【解决方案1】:

    您的问题是因为它不是virtual。不是因为你没有二传手。

    Moq 无法建立代理,因为它无法覆盖您的属性。您需要使用接口、虚拟方法或抽象方法。

    【讨论】:

    • 将此属性设置为虚拟有缺点吗?
    • 仅当您认为子类override-ing 具有风险时。基本上没有什么值得注意的,除非它是一个超级安全的函数,你不能相信其他类会正确,但是你不应该嘲笑它们,因为它们不会公开。
    • 这个答案现在已经过时了,因为 Moq 能够模拟非虚拟属性。
    • @krillgar 你能提供更多文档的链接吗?
    【解决方案2】:

    您可以在模拟对象上使用.SetupGet

    例如。

    [Test]
    public void DoOneStep ()
    {
        var mock = new Mock<PairOfDice>();
        mock.SetupGet(x => x.Value).Returns(1);
        PairOfDice d = mock.Object;
        Assert.AreEqual(1, d.Value);
    }
    

    更多详情请参阅here

    【讨论】:

    • 还是一模一样的问题,就是上面说的问题是不是虚拟的。
    • SetupGet 是正确的方法,不管和正确的答案。创建一个永远不会被覆盖或不需要的字段的虚拟是很愚蠢的,并且可能违反开发人员想要保护的内容。这是一个简单的问题,将字段设为虚拟可能影响不大,但在现实世界中,将某些内容设为虚拟只是为了测试它是不正确的,这就是您可以使用 SetupGet 模拟该值的原因。
    • @Jim,您的链接现在转到 404,您有什么办法可以更新它吗? +1 出于与 iGanja 上述相同的原因。
    • 您可以为该类创建一个接口,然后使用和模拟该接口 - 消除使东西不必要地虚拟化的要求。使用接口而不是具体类来编写测试要好得多。如果需要的话,还可以使用 IoC。旁注:将超链接的 "here" 放在屏幕阅读器上很烦人。
    猜你喜欢
    • 2014-01-07
    • 2019-06-16
    • 2011-11-30
    • 1970-01-01
    • 2021-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多