【问题标题】:Overriding protected methods in Moq在 Moq 中覆盖受保护的方法
【发布时间】:2013-10-03 02:41:38
【问题描述】:

我有一个实现抽象类的类。抽象类有一个protected virtual 方法,如图所示:

protected virtual void OnAction(string action, object result);

实现抽象类的类有一个方法,完成后调用base.OnAction

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

我的起订量设置如下:

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

中断我的基本抽象类OnAction 方法确认它仍在被调用。

我本质上是希望 Moq 在它的发射类中做同样的事情:

public override OnAction(string action, object result) { // do nothing }

【问题讨论】:

    标签: c# moq


    【解决方案1】:

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

    你现在的样子是这样的:

    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 方法,您是在模拟从未调用过的东西,因为具体的 DoTheHerple 调用仍然调用基类实现。

    解决这个问题的一个丑陋的方法是覆盖子类中的方法,并在那里调用基类方法,然后在子类方法中调用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); }
    }
    

    也可以。

    【讨论】:

    • 我相信您应该能够在不指定 basethis 甚至覆盖它的情况下执行 OnAction
    • @Matthew 最初误解了您的意图,您是对的,只需调用 OnAction 即可让模拟按描述工作,而无需在子类中指定覆盖。
    • @PrestonGuillot 感谢您的回答,这让我意识到我实际上做错了什么;我调用的是 base.OnAction 而不是 OnAction。
    • 问题是:派生类Herple是否覆盖了虚方法OnAction本身?因为如果没有,为什么它使用语法base.OnAction(...) 而不是简单的this.OnAction(...)OnAction(...)?我认为人们有时会过多地使用base 关键字。根据经验,如果可以避免,请不要使用base
    猜你喜欢
    • 2013-07-01
    • 2011-08-04
    • 2015-10-01
    • 2022-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-26
    • 1970-01-01
    相关资源
    最近更新 更多