C# 重写Moq中的受保护方法

C# 重写Moq中的受保护方法,c#,moq,C#,Moq,我有一个实现抽象类的类。抽象类有一个受保护的虚拟方法,如图所示: protected virtual void OnAction(string action, object result); 实现抽象类的类有一个方法,该方法在完成时调用base.OnAction 我试图在我的单元测试中覆盖OnAction实现的行为,因为我只尝试单元测试,而不尝试集成测试 我的最低起订量呼叫设置如下: mock.Protected().Setup("OnAction", ItExpr.IsAny<stri

我有一个实现抽象类的类。抽象类有一个受保护的虚拟方法,如图所示:

protected virtual void OnAction(string action, object result);
实现抽象类的类有一个方法,该方法在完成时调用
base.OnAction

我试图在我的单元测试中覆盖OnAction实现的行为,因为我只尝试单元测试,而不尝试集成测试

我的最低起订量呼叫设置如下:

mock.Protected().Setup("OnAction", ItExpr.IsAny<string>, ItExpr.IsAny<object>());

我不知道为什么您会期望不同,您正在模拟一个在具体实现中从未调用过的方法

您当前拥有的内容如下所示:

public abstract class Derple
{
    protected virtual void OnAction(string action, object result) { Console.WriteLine("Derple"); }
}

public class Herple : Derple
{
    public void DoTheHerple(string action, object result) { base.OnAction(action, result); }
}
因此,通过模拟
Herple
OnAction
方法,您模拟的是从未调用过的东西,因为具体的
方法Herple
调用仍在调用基类实现

解决这个问题的一个丑陋的方法是重写子类中的方法,并在那里调用基类方法,然后在子类方法中调用
this.OnAction

public abstract class Derple
{
    protected virtual void OnAction(string action, object result) { Console.WriteLine("Derple"); }
}

public class Herple : Derple
{
    protected override void OnAction(string action, object result) { base.OnAction(action, result); }
    public void DoTheHerple(string action, object result) { this.OnAction(action, result); }
}
这将使您的测试功能如您所愿,但可以说这表明您的设计中存在一个必要的缺陷

*编辑

正如Matthew所指出的,覆盖实际上并不是这项工作所必需的

public class Herple : Derple
{
    public void DoTheHerple(string action, object result) { OnAction(action, result); }
}

同样有效

我相信您应该能够在不指定
base
this
的情况下执行
OnAction
,甚至不重写它。@Matthew最初误解了您的意图,您是对的,只需调用
OnAction
就可以让模拟按所述工作,没有在子类中指定重写。@PrestonGuillot谢谢你的回答,它让我意识到我到底做错了什么;我调用base.OnAction而不是OnAction。问题是:派生类
Herple
是否覆盖虚拟方法
OnAction
本身?因为如果没有,为什么它使用语法
base.OnAction(…)
而不是简单地
this.OnAction(…)
OnAction(…)
?我认为人们有时会过多地使用
base
关键字。根据经验,如果可以避免,请不要使用
base
public class Herple : Derple
{
    public void DoTheHerple(string action, object result) { OnAction(action, result); }
}