我有一个文件 - 在一个大型遗留代码库中 - 包含访问数据库的方法。 没有使用类,只有带有方法声明的头文件和带有实现的源文件。
我希望覆盖这些方法以消除单元测试期间的数据库访问。
我想到了以下几个选项:
#ifdef PRODUCTION_CODE
包装整个源文件并创建一个包含存根的新源文件,并用相反的方式包装它,即使整个事件编译依赖。这里的问题是,在执行回归测试的构建系统中,我必须编译两次,一次是为了创建应用程序并进行回归测试,还有一段时间来创建单元测试可执行文件。任何推荐的方法吗?
答案 0 :(得分:1)
如何获取现有函数,将代码移入新类并从现有函数中调用新方法,然后在测试期间覆盖此类?
像这样:
static DBAccessClass dac = new DBAccessClass ();
void origFunction() { dac.origFunction(); }
在测试中:
dac = new DBAccessMockup();
答案 1 :(得分:1)
您可以尝试在链接器级别覆盖。有两个不同的.cpp文件,用于实现描述数据库接口的标题中的功能 - 一个调用真实数据库,一个调用伪接口。链接单元测试时,将其替换为另一个(GNU中的目标特定变量可能有帮助)。
答案 2 :(得分:0)
您可能还想看看Michael Feathers的书Working Effectively with Legacy Code。他不仅讨论了这些类型的问题,而且还包括C ++中的大量例子(除了Java,C和C#之外)。 Feathers也是CppUnit的原创者。
答案 3 :(得分:0)
- 将文件转换为类并覆盖方法。 [...]
- 用#ifdef [...]
包装整个源文件 醇>
如果可能,请使用1,因为您将有一个集中的方式来引用数据库代码(类指针而不是X函数)。这意味着模块化,易于替换实现(使用存根或其他数据库后端)和更多封装的代码。
如果选择2,请考虑替换函数的实现。也就是说,在原始函数内部,使用测试代码(基于if
)。
如果在测试环境中运行,您测试的代码是完全不可知的,性能损失可以忽略不计(在大多数情况下if(booleanFlagHere)
成本可以忽略不计)并且您根本不需要修改测试代码)。