从派生的 class 中起订基数 class 函数
Moq a base class function from a derived class
我是 Moq 的新手,我刚刚看了 Moqing 上的 pluralsight 视频,所以我觉得有能力去写一些测试。我有一个 Base Class 让我们说 Sheet 它实现了一个接口 ISheet。 Sheet 是页面的基础 class:
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
}
}
我覆盖了基础 class 中的一种方法,即 CreateSheet()
,但我想测试调用基础 class 中的 BuildSheet()
方法从我派生的 class:
所以在我的测试中 Class,我 Moq SUT 而不是接口
var MockSheet = new Moq<Page>();
调用方法:
var actual = MockSheet.Object.CreateSheet();
然后验证
MockSheet.Verify(x => x.BuildSheet(), Times.AtLeastOnce);
相反,我得到 MockException “预期调用模拟至少一次,但从未执行过。 CreateSheet 方法永远不会被调用。如果我将他的 CreateSheet 方法更改为:
public void CreateDocSheet() // removed override
{
BuildSheet() // base classses implementation
}
并在测试调用中:
var actual = MockSheet.Object.CreateDocSheet();
有效。我不明白为什么。我相信从功能上讲,这是一种有效的编码方式,我有 sheet,它有 2 页,我有一个接口,它定义了所有应该实现的功能和属性,我在基础 class,但并非所有方法都需要在派生的 class 中实现,因此,一些方法被重写,一些使用基础 class 实现。请解释为什么使用函数的覆盖版本会出现问题?
Moq 用于模拟被测系统的一个或多个依赖项,以便您可以将其与应用程序的其余部分或外部性隔离开来,而不是用于替换被测系统.它不是您在此处尝试执行的操作的正确工具。
如果你改变
var MockSheet = new Moq<Page>();
进入
var MockSheet = new Moq<Page> { CallBase = true, };
您的模拟(您可以将其视为 Page
的派生 class)将在模拟自己的 CreateSheet
覆盖中从 Page
调用实现。
默认行为(如果您不更改 CallBase
)是 Moq 覆盖每个方法并且 属性 它可以,并使用 empty 实施。将 CallBase
设置为 true
会使 Moq 调用 Page
实现,就像我说的那样。
(当然,如果你想让CreateDocSheet
做一些不平凡的事,就用MockSheet.Setup(x => x.CreateDocSheet()).Callback(() => { /* something */ })
。)
在您从 CreateSheet
中删除 virtual
修饰符的情况下,Moq 无法再覆盖或 mock 此成员。想一想:Moq "mock" 怎么可能是非虚拟方法?因此,该调用完全绕过了 Moq 的 class。
我是 Moq 的新手,我刚刚看了 Moqing 上的 pluralsight 视频,所以我觉得有能力去写一些测试。我有一个 Base Class 让我们说 Sheet 它实现了一个接口 ISheet。 Sheet 是页面的基础 class:
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
}
}
我覆盖了基础 class 中的一种方法,即 CreateSheet()
,但我想测试调用基础 class 中的 BuildSheet()
方法从我派生的 class:
所以在我的测试中 Class,我 Moq SUT 而不是接口
var MockSheet = new Moq<Page>();
调用方法:
var actual = MockSheet.Object.CreateSheet();
然后验证
MockSheet.Verify(x => x.BuildSheet(), Times.AtLeastOnce);
相反,我得到 MockException “预期调用模拟至少一次,但从未执行过。 CreateSheet 方法永远不会被调用。如果我将他的 CreateSheet 方法更改为:
public void CreateDocSheet() // removed override
{
BuildSheet() // base classses implementation
}
并在测试调用中:
var actual = MockSheet.Object.CreateDocSheet();
有效。我不明白为什么。我相信从功能上讲,这是一种有效的编码方式,我有 sheet,它有 2 页,我有一个接口,它定义了所有应该实现的功能和属性,我在基础 class,但并非所有方法都需要在派生的 class 中实现,因此,一些方法被重写,一些使用基础 class 实现。请解释为什么使用函数的覆盖版本会出现问题?
Moq 用于模拟被测系统的一个或多个依赖项,以便您可以将其与应用程序的其余部分或外部性隔离开来,而不是用于替换被测系统.它不是您在此处尝试执行的操作的正确工具。
如果你改变
var MockSheet = new Moq<Page>();
进入
var MockSheet = new Moq<Page> { CallBase = true, };
您的模拟(您可以将其视为 Page
的派生 class)将在模拟自己的 CreateSheet
覆盖中从 Page
调用实现。
默认行为(如果您不更改 CallBase
)是 Moq 覆盖每个方法并且 属性 它可以,并使用 empty 实施。将 CallBase
设置为 true
会使 Moq 调用 Page
实现,就像我说的那样。
(当然,如果你想让CreateDocSheet
做一些不平凡的事,就用MockSheet.Setup(x => x.CreateDocSheet()).Callback(() => { /* something */ })
。)
在您从 CreateSheet
中删除 virtual
修饰符的情况下,Moq 无法再覆盖或 mock 此成员。想一想:Moq "mock" 怎么可能是非虚拟方法?因此,该调用完全绕过了 Moq 的 class。