C++ 没有虚拟方法的模拟类
我刚刚开始使用GoogleMock对生产代码进行单元测试。我想要模拟的类中没有虚拟方法。通过阅读GoogleMock上的一些内容,难道不可能模拟这样一个类吗?请记住,我不想对源代码进行任何更改C++ 没有虚拟方法的模拟类,c++,googletest,googlemock,C++,Googletest,Googlemock,我刚刚开始使用GoogleMock对生产代码进行单元测试。我想要模拟的类中没有虚拟方法。通过阅读GoogleMock上的一些内容,难道不可能模拟这样一个类吗?请记住,我不想对源代码进行任何更改 class Test { Test(void); virtual ~Test() {} Add(); }; int Test::Add() { return 1; } class MockTest : public Test { public: MOCK_MET
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”中定义,并且该类是多态的(在本例中是多态的,因为存在虚拟析构函数),则可以替换该文件中的所有定义,以使它们看起来像是虚拟的,即使它们不是:
#include "Test.hpp"
#include <gmock/gmock.h>
class MockTest : public Test
{
public:
MOCK_METHOD0(Add, int());
MOCK_CONST_METHOD0(Print, void());
};
#包括“Test.hpp”
#包括
类MockTest:公共测试
{
公众:
模拟方法0(添加,int());
模拟常量方法0(打印,void());
};
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";
}
int测试::添加()
{
如果(自动*mock=dynamic_cast(此))
返回mock->Add();
//接下来,如果代码调用了Add-on,该怎么办
//实际上不是模拟测试的测试。这可能
//是存根实现、实际实现或
//可以故意终止、抛出或记录gtest错误。
添加_FAILURE()打印();
返回;
}
添加_失败()