【问题标题】:GMOCK base class methods in derived class派生类中的 GMOCK 基类方法
【发布时间】:2018-05-16 06:01:39
【问题描述】:

我有一个类继承自另一个类,如下所述:

class A
{
public:
    virtual void Show(){}
};

class B : public A
public:
    void BMethod1(){Show()}
};

现在我正在为 B 类编写测试用例 - 所以我模拟了 A 类:

class MockA : public A
{
    MOCK_METHOD0(Show, void());
};

下面是我的谷歌测试框架测试用例:

TEST(BTEST , ShowMethod)
{
    B bobj;
    MockA aobj;
    EXPECT_CALL(aobj , Show());
    bobj.BMethod1(); // updated as from bobj.METHOD0()
}

但是测试用例正在调用实际的 A::Show() 实现——在这种情况下如何调用 MockA::Show() 的 Mocked 版本?

====================更新========================== =======

下面的实现对我有用:

class A
{
public:
    virtual void Show(){}
};

class B : public A
public:
    void BMethod1(){Show()}
};

class BMock : public B
{
public:
   MOCK_METHOD0(Show, void());
};

现在使用 BMock 对象来测试你 B 类所需的方法

【问题讨论】:

  • 你可以更改class B吗?
  • 如果它解决了问题,我可以,并且还想验证是否存在其他机制

标签: c++ c++11 gmock


【解决方案1】:

您必须将 Show() 设为虚拟才能获得 MockA::Show() 而不是 A::Show()。

【讨论】:

  • 我试过了,但还是同样的问题-请您详细提供方法实现
  • 在MockA类中也要注意public关键字
  • 这样的? class A { public: virtual void Show(){} }; class MockA : public A { public: MOCK_METHOD0(Show, void()); };
  • @Nayfe 您的回答并没有真正解决 OP 的问题,但说明了启用 MockA 覆盖该功能的必要事实。
【解决方案2】:

首先:

    bobj.METHOD0();

完全错误。 METHOD0 不是访问模拟函数的有效符号。

你要测试的是B::BMethod1()调用A::Show(),对吧?
所以将该行更改为

    bobj.BMethod1();

您可以更改类B 以将其基类实现作为模板参数:

class A
{
public:
    virtual void Show(){}
 // ^^^^^^^ See note 1
};

template<class Base>
class B : public Base
public:
    void BMethod1(){Show()}
};

然后你使用

B<A> bobj;
bobj.BMethod1();

在您的生产代码中,并且

B<MockA> bobj;
EXPECT_CALL(bobj , Show());
bobj.BMethod1(); // <<< trigger the expectation

在您的单元测试代码中。


作为侧节点:

通过称为Mixin 的模板类型参数注入基类是一种众所周知的模式。
虽然 Mixins 主要是为了提供接口的分段实现,主要是为了组合公共接口实现。

但是,在尝试对有关这些方式的类进行单元测试时遇到这种情况,如果我在那里有设计缺陷,我会自动提出问题:

B 真的是A,还是说它打算使用A 的实例作为拥有或引用的成员变量?

如果我需要在单元测试中进行测试,我会考虑将 B 类重构为类似

class B {
    A& a_;
public:
    B(A& a) a_(a) {}
    void BMethod1() { a_.Show(); }
};

并相应地调整测试场景:

TEST(BTEST , ShowMethod)
{
    MockA aobj;
    B bobj(aobj);
    EXPECT_CALL(aobj , Show());
    bobj.BMethod1();
}

至于你的评论

目的是测试用例可以返回模拟值 - EXPECT_CALL(mMockA, show()) .WillOnce(Return(false));

这应该适用于上面的示例:

EXPECT_CALL(bobj, Show()) .WillOnce(Return(false));

但要求Show() 声明为

virtual bool Show();

在课堂上A 和喜欢

MOCK_METHOD0(Show, bool());

MockA 类中。


1)virtual 声明是必要的,以允许 MockA 覆盖原始实现。

【讨论】:

【解决方案3】:

下面的实现对我有用:

class A
{
public:
    virtual void Show(){}
};

class B : public A
public:
    void BMethod1(){Show()}
};

class BMock : public B
{
public:
   MOCK_METHOD0(Show, void());
};

现在为您的测试用例使用 BMock 对象

【讨论】:

    【解决方案4】:

    您可以使用Isolator++ 无需设置即可创建测试:

    class A
    {
    public:
        void Show() {}
    };
    
    class B : public A
    {
    public:
        void BMethod1() { Show(); }
    };
    
    TEST(BTEST, ShowMethod)
    {
        B bobj;
        auto aobj = FAKE<A>();
    
        bobj.BMethod1();
    
        ASSERT_WAS_CALLED(aobj->Show());
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-06
      • 1970-01-01
      • 2014-03-17
      • 2014-09-05
      • 1970-01-01
      • 2018-10-12
      • 2019-07-25
      相关资源
      最近更新 更多