模板或链接接缝依赖注入有哪些替代方法可用于测试非虚方法?

Sam*_*man 7 c++ testing templates dependency-injection

我正在尝试测试对代码有很多依赖性的代码,这些代码无法更改,并且通常不使用虚拟方法.它也是一个高性能的场景,所以我可以想象我们自己的代码中的一些地方,我们不想使用虚拟方法.非虚方法对测试场景很重要,所以我想嘲笑它们.

据我了解,有两个主要选择:

  1. 模板依赖注入:Google称之为hi-perf依赖注入.mock不再是依赖项的派生类,它将替换为模板类.它被实例化为原始依赖项的生产类和用于测试的模拟类.

  2. 链接接缝:将测试类命名为与生产类相同,并在链接测试时使用链接描述将其替换为生产实现.

我已成功使用1.但它很快就会失控:我会将大部分代码库模板化以处理依赖项的非虚方法.2.看起来相当不优雅 - 或许更重要的是 - 对大多数人来说会更加陌生.

有替代方法吗?当人们依赖于他们无法控制的大型非虚拟代码库时,人们会怎么做?

Cor*_*sto 2

我之前见过另一种方法:创建一个仅包含内联成员函数的瘦包装类,这些函数仅转发到外部库,但通过预处理器宏使它们有条件地虚拟。然后在用于测试的构建中定义宏,以便可以覆盖模拟中的成员函数,而在生产构建中不定义宏,以便编译器可以内联库调用作为所有成员函数的定义包装纸的形状是可见的。

#ifdef TEST_BUILD
#define VIRTUAL virtual
#else
#define VIRTUAL
#endif

class library_wrapper {
public:
    VIRTUAL void foo(int i) {
        ::externallib::foo(i);
    }
};

class library_wrapper_mock : public library_wrapper {
public:
    MOCK_METHOD1(foo, void(int));
}
Run Code Online (Sandbox Code Playgroud)

当然,这意味着您无法再测试您正在发布的构建,但这是在生产构建中不使用虚拟函数的性能增益的权衡。

另一种选择是使用不同的模拟库,例如 Hippomocks,它也可以通过使用特定于平台的技巧来覆盖“真实”函数中的指令以跳转到模拟版本来模拟自由函数(只要它们不是内联的)。