如何使用 gmock 模拟调用 base class

How to mock calling to base class with gmock

给定 2 类,如下所示:

class Base
{
public:
    virtual void doSmt(void);
}

class Derived : public Base
{
    void doSmt(void) { Base::doSmt(); }
}

Class我需要测试的是Derived。但是我不想在 Base 中更深入,我只是想检查 doSmt()

中是否调用了对 Base 的调用

像这样:

TEST_F(Derived, DoSmt)
{
    EXPECT_CALL(Base, doSmt()).Times(1);
    testedInstance.doSmt();
}

因为我已经测试了Base,而且Base被2继承了类。

有什么办法吗?

正如所写,没有(直接的)方法来模拟对 Base::doSmt() 的显式调用。在不知道 Base class 的使用上下文的情况下很难做出判断,但我的猜测是使用组合而不是继承来重用所提供的功能会更好通过 Base。这将使测试 classes 依赖于 Base 变得容易得多,因为您可以简单地将模拟 Base class 注入 Derived 并验证 Base 被适当地调用。

除了 gmock,我还被分配为 "evil" 设计编写单元测试。从一开始就比我更难,但我也有自己的解决方案。

虽然比我简单(再次:D)

1.Insert 到 Base class header 需要的任何模拟。或者您可以创建一个新的并指定其路径 include。

class Base
{
public:
    MOCK_METHOD0(mock_doSmt, void());
    void doSmt(void);
}

2.For 调用 Base 模拟方法,只需创建 BaseStub.cpp

此源仅用于模拟。因此,您必须使用 BaseStub.cpp 而不是 Base.cpp

来编译 & link
void Base::doSmt(void) { mock_doSmt(); }

3.When 测试

EXPECT_CALL(*reinterpret_cast<Base*>(&derivedInstance), mock_doSmt()).Times(1);

mock_doSmt 而不是 doSmt

这种方式也可以解决单例问题。像上面那样创建 SingletonStub,在 SetUp() 中只是 singletonInstance = Singleton::getInstance();

记住:这样,您有 2 个来源和 2 个 header。

面对这个笨蛋,我意识到应该用#include <...>而不是#include "..."

因为当您指定包含目录时,#include <...> 会让您有更多的控制权。

我想分享的另一个重要信息是

不要抽象太多你的 OOP。原因 之后这会让你(或你的同事)陷入非常大的麻烦。继承不要超过2级,1个接口1个继承即可。