没有虚拟方法的模拟类
Mocking class with no virtual methods
我刚刚开始使用googlemock对生产代码进行单元测试。我想模拟的类内部没有虚拟方法。从谷歌mock上读到的一点内容来看,难道不可能这样模拟一个班级吗?请记住,我不想对来源做任何更改。
class Test
{
Test(void);
virtual ~Test() {}
Add();
};
int Test::Add()
{
return 1;
}
class MockTest : public Test
{
public:
MOCK_METHOD0(Add,int(void));
};
可能有一种方法,但它不如覆盖虚拟函数的简单方法好。
首先,如果函数不是虚拟的并且是内联的,那么你很可能运气不好。当编译器看到对obj.Add()
或ptr->Add()
的调用时,该函数不是虚拟的这一事实意味着它不需要担心Test::Add()
以外的某个函数可能需要成为实际调用的函数。因此,它很可能直接内联了Add
定义中的代码,在这种情况下,替换它几乎是不可能的,或者它将Test::Add()
的弱链接副本放入与调用它的函数相同的对象文件中。在第二种情况下,您可以使用链接器技巧替换它,取决于您使用的平台-直到稍后,编译器才决定内联它。
如果只是您不想修改的类Test
,但您可以更改使用Test
作为依赖项并将由单元测试测试的代码,则可以进行模板依赖项注入。但这个问题听起来可能你也不想修改那个代码。
现在,假设函数不是内联的,并且是在某个文件"Test.cpp"中定义的,并且类是多态的(在本例中是因为虚拟析构函数),您可以替换该文件中的所有定义,使它们看起来像是虚拟的,即使它们不是:
-
像往常一样编写Google Mock类,其中包含您希望能够检测到Mock的函数。
#include "Test.hpp" #include <gmock/gmock.h> class MockTest : public Test { public: MOCK_METHOD0(Add, int()); MOCK_CONST_METHOD0(Print, void()); };
(我在示例中添加了一个const方法,以显示如何处理它们。)
-
在相同的单元测试代码中,为模拟函数编写定义,如下所示。
int Test::Add() { if (auto* mock = dynamic_cast<MockTest*>(this)) return mock->Add(); // Next comes what to do if the code ever calls Add on // a Test which is not actually a MockTest. This could // be a stub implementation, an actual implementation, or // could intentionally terminate, throw, or note a gtest error. ADD_FAILURE() << "Test is not a MockTest"; return 0; } void Test::Print() const { if (auto* mock = dynamic_cast<const MockTest*>(this)) { mock->Print(); return; } ADD_FAILURE() << "Test is not a MockTest"; }
您可能还需要在Test.cpp文件中至少为其他定义编写存根,以使链接器满意。这并不一定意味着它们会被调用或以其他方式使用。
链接单元测试时,请确保未提供真正的test.cpp文件。如果它通常是库的一部分,则可能需要在命令行中列出该库中的其他文件。这可能会导致依赖顺序问题和/或循环依赖问题。GNU的链接器有"-Wl,--start group…-Wl,-end group",通过在循环中重复尝试一些对象和/或库来处理循环链接问题,直到尽可能多地得到解决;我不确定其他系统相关文章:
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 在静态库中嵌入类方法
- 如何制作一个将函数作为参数的类方法
- 从父类方法返回子类对象
- 使用用户定义的参数调用future/async并调用类方法
- 重载类方法的不明确调用
- 单独定义模板化嵌套类方法的正确语法
- 绑定派生类方法C++从实例范围之外的分隔 std::function 变量调用
- 如何访问由共享指针保存的类方法?
- 将子类方法声明为基类的友元
- 我的模板类方法返回错误类型?
- Qt将信号与另一个类方法连接
- 我无法使用C++指针指向类方法返回的 std::vector
- 如何在成为指向基类的指针后保留对子类方法的使用?
- 如何模拟调用其基类方法的派生类
- 如何使用 gmock 模拟类中的模板方法
- 没有虚拟方法的模拟类
- 如何用模板方法(c++)模拟类中的多态性
- Hippomocks 中的模拟基类方法
- c++中的模拟非类方法