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

mwngjboj  于 2023-02-10  发布在  其他
关注(0)|答案(3)|浏览(101)

我是一个相当新的软件开发人员,目前正在为一个几年前开始的现有C++项目添加单元测试。由于非技术原因,我不允许修改任何现有代码。我所有模块的基类都有一堆用于设置/获取数据以及与其他模块通信的方法。
因为我只想对每个模块进行单元测试,所以我希望能够对所有模块间通信方法使用固定值。()检查另一个模块是否处于活动状态,我想让它根据我正在做的测试类型返回true或false,我一直在研究Google Test和Google Mock,它支持模拟非虚方法。但是,所描述的方法(https://google.github.io/googletest/gmock_cook_book.html#MockingNonVirtualMethods)要求我将原始方法"模板化",以接受真实对象或模拟对象。由于前面提到的要求,我无法在基类中模板化我的方法,因此我需要一些其他方法来模拟这些虚方法
基本上,我想要模拟的方法在某个基类中,我想要单元测试和创建模拟的模块是那个基类的派生类,在我的基类Module和我想要测试的模块之间有中间模块。
我会很感激任何建议!
谢谢你,
JW

    • 编辑:更具体的示例**

我的基类是rootModule,我想测试的模块是leafModule,有一个中间模块继承了rootModule,leafModule继承了这个中间模块。
在我的leafModule中,我想测试doStuff()方法,该方法调用rootModule类中定义的非虚拟GetStatus(moduleName)。我需要以某种方式使GetStatus()返回选定的固定值。模拟对我来说是新事物,所以使用模拟对象是否正确?

but5z9lq

but5z9lq1#

替换非虚函数有几种不同的方法,一种是重新声明它们,并为你想测试的每一组不同的非虚函数编译一个新的测试可执行文件,这几乎是不可伸缩的。
第二种选择是使它们虚拟化以进行测试,大多数编译器允许您在命令行上定义一些内容,因此使用-DTEST_VIRTUAL=virtual或-DTEST_VIRTUAL编译代码,以使它们虚拟化或正常化,这取决于代码是否处于测试状态。
第三个可能有用的选择是使用一个模拟框架,它允许您模拟非虚函数。(关于中立性等的免责声明),我们最近添加了在X86平台上模拟普通C函数的功能。这可以通过一些工作扩展到非虚拟成员函数,这将是您正在寻找的。请记住,如果你的编译器可以同时看到函数的使用和定义,那么它可能会内联它,模拟可能会失败,尤其是对于在头文件中定义的函数。
如果常规的C函数模拟对您来说足够了,那么您可以像现在这样使用它。

jv4diomz

jv4diomz2#

我会写一个Perl/Ruby/Python脚本来读入原始的源代码树,然后在不同的目录下写出一个模拟的源代码树,你不必为了替换函数定义而完全解析C++。

nx7onnlm

nx7onnlm3#

一种方法是为测试指定不同的源代码。假设您的生产目标使用rootModule.hrootModule.cpp。为您的测试目标使用不同的源代码。您可以通过更改include路径指定不同的头文件,以便#include "rootModule.h"实际加载unittest/rootModule.h。然后根据您的意愿模拟rootModule。

相关问题