Gmock Base类方法中的派生类方法

GMOCK base class methods in derived class

本文关键字:类方法 派生 Gmock Base      更新时间:2023-10-16

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

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

现在我正在编写B类的测试用例 - 所以我嘲笑A类:

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

以下是我的Google测试框架测试案例:

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

但是测试用例正在调用实际a :: show()实现 - 在这种情况下如何调用overed :: show()的模拟版本?

=========================================================================

下面的实现为我带来了技巧:

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类所需方法

您必须使Show()Virtual才能获得Mocka :: show()而不是a :: show()。

首先:

    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覆盖原始实现。

下面的实现对我有用:

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

现在,将BMOCK对象用于测试用例

您可以使用隔离器 创建测试而无需设置:

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());
}