在不编辑生产代码的情况下用C++模拟非虚方法?

wk1*_*989 19 c++ unit-testing mocking googlemock

我是一个相当新的软件开发人员,目前正在为几年前开始的现有C++项目添加单元测试.由于非技术原因,我不允许修改任何现有代码.我所有模块的基类都有一堆设置/获取数据和与其他模块通信的方法.

由于我只想对每个单独的模块进行单元测试,因此我希望能够为所有模块间通信方法使用预设值.即一个方法Ping(),它检查另一个模块是否处于活动状态,我希望根据我正在进行的测试类型返回true或false.我一直在研究Google Test和Google Mock,它确实支持模拟非虚拟方法.但是,所描述的方法(http://code.google.com/p/googlemock/wiki/CookBook#Mocking_Nonvirtual_Methods)要求我"模板化"原始方法以接受真实或模拟对象.由于前面提到的要求,我无法去基类中模拟我的方法,所以我需要一些其他方法来模拟这些虚方法

基本上,我想要模拟的方法是在一些基类中,我想要单元测试的模块和创建模块的是该基类的派生类.我的基本Module类和我想测试的模块之间有中间模块.

我很感激任何建议!

谢谢,

JW

编辑:一个更具体的例子

我的基类是rootModule,我要测试的模块是leafModule.有一个继承自rootModule的中间模块,leafModule继承自这个中间模块.

在我的leafModule中,我想测试doStuff()方法,该方法调用rootModule类中定义的非虚拟GetStatus(moduleName).我需要以某种方式使GetStatus()返回一个选定的固定值.模拟对我来说是新的,所以使用模拟对象甚至是正确的方法?

das*_*ndy 13

有一些不同的方法可以替换非虚函数.一种方法是重新声明它们,并为您要测试的每组不同的非虚函数编译一个新的测试可执行文件.这几乎不可扩展.

第二种选择是使它们虚拟以进行测试.大多数编译器允许您在命令行上定义某些内容,因此使用-DTEST_VIRTUAL = virtual或-DTEST_VIRTUAL编译代码,使其成为虚拟或正常,具体取决于它是否在测试中.

可以使用的第三个选项是使用模拟框架,它允许您模拟非虚函数.我是HippoMocks的作者(关于中立性的免责声明等),我们最近添加了在X86平台上模拟普通C函数的功能.这可以通过一些工作扩展到非虚拟成员函数,并且将是您正在寻找的.请记住,如果您的编译器一次可以看到函数的使用和定义,它可能会内联它并且模拟可能会失败.这尤其适用于标头中定义的函数.

如果常规C函数模拟对您来说已足够,您可以像现在一样使用它.


Zan*_*ynx 3

我会编写一个 Perl/Ruby/Python 脚本来读取原始源代码树,并在不同的目录中写出模拟源代码树。您不必完全解析 C++ 即可替换函数定义。

  • 这可能会起作用,但是在我看来,只有两个源树并在其中一个源树中将基类方法更改为虚拟方法会更简单。对于负责源代码控制系统的人员来说,会有一些负面影响。开发人员还必须调整自己以编写 2 个工作修订版的代码。我正在寻找一种解决方法,它可以让我将单元测试集成到可以一次性构建(和执行)的单个源代码树中。我不确定这是否可能。 (3认同)