如何使用 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个继承即可。
给定 2 类,如下所示:
class Base
{
public:
virtual void doSmt(void);
}
class Derived : public Base
{
void doSmt(void) { Base::doSmt(); }
}
Class我需要测试的是Derived
。但是我不想在 Base
中更深入,我只是想检查 doSmt()
像这样:
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
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个继承即可。