c++ - 使用预处理器模拟非虚拟方法
问题描述
我正在使用 C++ 开发一个嵌入式项目,其中资源有点有限。这意味着除非我真的需要它们,否则我会尽量小心使用过多的虚拟方法。我计划开始使用 Gtest 实施单元测试。
因为项目的代码量不算太大,所以大部分代码都是直接写在头文件中的。唯一的惩罚是编译时间多一点。因为编译需要大约 20 秒,所以这不是问题,而且我认为使代码更易于编写/阅读。
如果项目在 Windows 中运行,我将全力以赴创建新的抽象层(或添加接缝类)并在需要它们进行单元测试的地方拥有更多的虚拟方法。由于项目的性质,我不想仅仅为了单元测试的目的而添加额外的虚拟方法。我认为这样做是有效的,但在资源稀缺时似乎有点不合理。
该项目运行良好,并且可以进行单元测试,因此我希望将代码修改保持在最低限度。该问题的解决方案之一是使用“高性能依赖注入”对模板进行一些技巧。这对我来说似乎是鸭式打字,并且仍然需要修改使用该类的原始源代码。
我在想为什么不只使用预处理器:
#ifdef TEST
#define TESTABLE virtual
#else
#define TESTABLE
#endif
然后,当需要模拟一个方法时,您总是可以修改该类的原始源代码并编写如下内容:
TESTABLE void somePreviouslyUnmockeableMethod(void);
我知道其中一个缺点是我现在有两个源代码,一个用于生产,一个用于测试。当一个人决定在单元测试时使用 Mock 类而不是真实类时,无论如何都会发生同样的情况。如果代码更改相当大,那么预处理器的更改可能是一个真正的问题,但我认为通过这个定义,它们被保持在最低限度。
这是一个有效的解决方案吗?我可能忽略了一些负面后果吗?
请注意,所有模块都已经包含一个可以轻松添加定义的ProjectSettings.h
文件。TESTABLE
解决方案
如果使类虚拟化真的太昂贵(即您测量这将是太多的开销),您可以使用高性能依赖注入技术。成本只是更长的编译时间,但没有运行时开销。在生产中,您使用真实对象和测试实例化您的类 - 使用具有与真实类相同签名的方法的模拟类。
推荐阅读
- flutter - 我正在尝试制作一个简单的应用程序来随机改变身体背景的颜色,但我在模拟器上得到的只是一个空白
- javascript - 浏览器通知可判定操作不起作用(javascript、vue.js) - 不再受支持吗?
- python - 从 IGraph (Python) 中的多个文件中读取图形
- html - 4列全角链接部分
- regex - 仅匹配第一次出现的正则表达式不起作用
- vba - 选择与否...单词自动删除句子后的空格
- debugging - 如何将 Xamarin.Android 输出写入 Windows 文本文件?
- sql - SQL 事务死锁
- security - 如何保护用户生成和使用的文件中的 IP 敏感数据
- python - Python:添加作为组第一行的列