1

我有一个文件 - 在一个大型遗留代码库中 - 包含访问数据库的方法。没有使用任何类,只有一个带有方法声明的头文件,以及带有实现的源文件。

我想覆盖这些方法以消除单元测试期间的数据库访问。

我想到了以下选项:

  1. 将文件放入类并覆盖方法。
    这里的主要缺点是它会导致整个代码库发生很多变化。
    不理想,虽然它确实改进了代码......
  2. 用 an 包裹整个源文件#ifdef PRODUCTION_CODE并创建一个包含存根的新源文件并用相反的东西包裹它,即使整个东西编译依赖。这里的问题是,在执行回归测试的构建系统中,我必须编译两次,一次是为了创建应用程序并进行回归测试,另外一次是创建单元测试可执行文件。

有什么推荐的方法吗?

4

4 回答 4

1

如何获取现有函数,将代码移到一个新类中并从现有函数中调用新方法,然后在测试期间覆盖这个类?

像这样:

 static DBAccessClass dac = new DBAccessClass ();

 void origFunction() { dac.origFunction(); }

在测试中:

 dac = new DBAccessMockup();
于 2009-10-27T18:11:40.037 回答
1

您可以尝试在链接器级别覆盖。有两个不同的 .cpp 文件,它们实现了描述 DB 接口的标头中的函数 - 一个调用真正的 DB,一个调用假接口。当您为单元测试链接时,将一个替换为另一个(GNU make 中的目标特定变量可能会有所帮助)。

于 2009-10-27T18:17:48.200 回答
0

您可能还想查看 Michael Feathers 的《有效地使用旧代码》一书。他不仅准确地讨论了这些类型的问题,而且本书还包含大量 C++ 示例(除了 Java、C 和 C#)。Feathers 也是CppUnit的原始创建者。

于 2009-11-18T13:39:20.187 回答
0
  1. 将文件放入类并覆盖方法。[...]
  2. 用#ifdef [...] 包裹整个源文件

如果可能,请使用 1,因为您将使用一种集中方式来引用数据库代码(类指针而不是 X 函数)。这意味着模块化、易于替换实现(使用存根或使用另一个数据库后端)和更多封装的代码。

如果您选择 2,请考虑替换功能的实现。也就是说,在原始函数内部,使用测试代码(基于if)。

您的测试代码是否在测试环境中运行是完全不可知的,性能损失可以忽略不计(if(booleanFlagHere)在大多数情况下是可以忽略不计的成本)并且您根本不必修改测试代码)。

于 2010-06-18T09:15:28.663 回答