【问题标题】:Moq a base class function from a derived classMoq 派生类的基类函数
【发布时间】:2016-04-20 01:23:59
【问题描述】:

我是 Moq 的新手,我刚刚观看了 Moqing 上的复数视频,所以我觉得自己有能力去写一些测试。我有一个基类,比如说 Sheet,它实现了 ISheet 接口。 Sheet 是页面的基类:

abstract class Sheet: ISheet
{
    public virtual void CreateSheet()  // Defined in ISheet
    {
    }
    public virtual void BuildSheet() // Defined in ISheet
    {
    }
    //and some abstract methods, etc.
}

public class Page : Sheet
{
    public override void CreateSheet()
    {
        BuildSheet(); // Base class implementation
    }
}

我覆盖了基类中的一个方法CreateSheet(),但我想测试基类中的BuildSheet() 方法是从我的派生类中调用的:

所以在我的测试课中,我 Moq SUT 而不是接口

var MockSheet = new Moq<Page>();

调用方法:

var actual = MockSheet.Object.CreateSheet(); 

然后验证

MockSheet.Verify(x => x.BuildSheet(), Times.AtLeastOnce);

相反,我得到 MockException “Expected Invocation on the mock 至少一次,但从未执行过。 CreateSheet 方法永远不会被调用。如果我将他的 CreateSheet 方法更改为:

public void CreateDocSheet() // removed override
{
    BuildSheet() // base classses implementation
}

在测试调用中:

var actual = MockSheet.Object.CreateDocSheet();  

它有效。我不明白为什么。我相信从功能上讲这是一种有效的编码方式,我有一张有 2 页的工作表,我有一个接口,它定义了所有应该实现的功能和属性,我在基类中实现了这些功能,但不是全部方法需要在派生类中实现,所以有些方法被覆盖,有些使用基类实现。请解释为什么使用该函数的覆盖版本会出现问题?

【问题讨论】:

    标签: c# moq


    【解决方案1】:

    如果你改变了

    var MockSheet = new Moq<Page>();
    

    进入

    var MockSheet = new Moq<Page> { CallBase = true, };
    

    您的模拟(您可以将其视为Page 的派生类)将在模拟自己的CreateSheet 覆盖中从Page 调用实现。

    默认行为(如果您不更改 CallBase)是让 Moq 覆盖它可以覆盖的每个方法和属性,并使用 empty 实现。正如我所说,将CallBase 设置为true 会使Moq 调用Page 实现。

    (当然,如果您想让CreateDocSheet 做一些不平凡的事情,请使用MockSheet.Setup(x =&gt; x.CreateDocSheet()).Callback(() =&gt; { /* something */ })。)

    如果您从CreateSheet 中删除了virtual 修饰符,Moq 将无法再覆盖或模拟此成员。想一想:Moq 如何“模拟”非虚拟方法?因此,调用完全绕过了 Moq 的类。

    【讨论】:

    • 虽然这都是很好且有用的信息,但 Moq 无法验证 Page.CreateSheet 调用 SheetBuildSheet 实现而不是 PageBuildSheet 实现。 Moq 只能记录对其模拟对象本身的代理的调用。
    • 感谢您的工作,也感谢您的解释。我认为必须有一种方法可以从派生类测试基类实现,而不必编写我本来不打算做的新函数。
    【解决方案2】:

    Moq 用于模拟您的被测系统的一个或多个依赖项,以便您可以将其与您的应用程序的其余部分或外部性隔离,而不是替换您的被测系统。这不是您在此处尝试执行的操作的正确工具。

    【讨论】:

      猜你喜欢
      • 2015-10-24
      • 2014-01-01
      • 2011-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-20
      相关资源
      最近更新 更多