如何在派生类中模拟基方法?

  • 本文关键字:模拟 方法 派生 c# moq
  • 更新时间 :
  • 英文 :


我想模拟以下代码的方法base.Generate(operation, model, builder, false);

public class ExtendedSqlServerMigrationsSqlGenerator : SqlServerMigrationsSqlGenerator
{
public ExtendedSqlServerMigrationsSqlGenerator(MigrationsSqlGeneratorDependencies dependencies, IMigrationsAnnotationProvider migrationsAnnotations) :base(dependencies, migrationsAnnotations){}
// this methode should be tested 
protected override void Generate(CreateIndexOperation operation, IModel model, MigrationCommandListBuilder builder, bool terminate)
{
base.Generate(operation, model, builder, false); // this line should be mocked
AddIncludeIndex(operation, builder, terminate);
}
protected void AddIncludeIndex(CreateIndexOperation operation, MigrationCommandListBuilder builder, bool terminate)
{
//some code
}
public void GenerateTest(CreateIndexOperation operation, IModel model, MigrationCommandListBuilder builder, bool terminate)
{
Generate(operation, model, builder, terminate);
}

我使用的模拟设置是:

var sut = new Mock<ExtendedSqlServerMigrationsSqlGenerator>(GetDependencies(), p2.Object) 
{ 
CallBase = true 
};
sut.Protected().Setup("Generate", true, ItExpr.IsAny<CreateIndexOperation>(), ItExpr.IsAny<IModel>(), ItExpr.IsAny<MigrationCommandListBuilder>(), ItExpr.IsAny<bool>());
sut.Object.GenerateTest(createIndexOperation.Object, new Model(), m3.Object, false);

目前我打电话给GenerateTest(). 问题是Generated方法被模拟了,而不是base.Generate我还尝试设置一个派生的 TestClass,它允许我从 testclass 调用受保护的方法。但也有同样的问题。

这与在没有反射的情况下嘲笑受保护的成员不同。我知道如何模拟对基类方法的调用,但不知道如何模拟相同的方法。

有关此类的一些背景信息

EF 可以基于模型生成 SQL 语句。为了扩展生成的 SQL,我将 DI 中的这个类替换为派生类。当EF调用generate时,我必须调用基类并添加一些额外的SQL语句。

我想嘲笑"base.generate"的原因是

  • 配置有效参数并不容易
  • 我对基类的实现细节不感兴趣。

这种情况似乎并不独特,并且期望有一种简单的方法来模拟这种情况。

虽然我认为您试图解决的问题在广义上非常有效,尤其是当基类进行您想要避免的系统/IO 调用时,我会指出之前相关问题中的回答,以表明 Moq 不是这里的正确工具。

Moq 旨在从您的 sut 中删除依赖项,而不是替换其中的功能。这是有道理的,因为 sut 中的函数通常会有副作用(尤其是当您尝试替换的函数的返回类型为 void 时)。

从历史上看,当我使用 EF 进行这种性质的测试时,我发现为每个测试类(或测试程序集)启动 localDb 并执行集成测试比为了单元测试而尝试单元测试更方便、更可靠。当然,这里有一些依赖项,您在迁移等方面使用代码优先。

最新更新