如何在C ++中存根/模拟非指针成员变量?

时间:2013-04-17 13:27:54

标签: c++ unit-testing mocking googlemock

许多关于单元测试的网站都说要向接口提取接口和代码(这很有意义),但这需要通过指针使用多态。是否有可能在没有指针的情况下实现这一点,所以我不必修改生产代码?我宁愿不使用指针和管理内存。

  • 允许条件编译。
  • 我特意使用gmock作为我的存根/模拟。

我研究过的一些事情是:

  • 使用参考
    • 涉及编写特殊副本构造函数或使其不可复制
    • 仍然需要使用new / delete
    • 来管理内存
    • 不确定这是否会导致不可预见的问题
  • 通过代码生成创建指针包装类的集合。通过一些额外的测试方法,界面保持不变。
    • 似乎可行,但需要保养
    • 我的意思下面的例子

请注意gmock模拟对象不可复制,因此我无法将构造函数注入它们。 (https://groups.google.com/forum/#!topic/googlemock/GD73UXjQowE/discussion

问题示例

class Example
{
public:
   Example();
   ~Example();

private:
   // I want to stub out _foo.
   Dependency _foo;
};

Pointer Wrapper类示例

#ifndef UNIT_TEST
   Foo _foo;
#else
   PtrWrapFoo _foo;
#endif

...

_foo.setImpl(StubFoo *aStubFoo);

...

void PtrWrapFoo::doSomething()
{
   _impl->doSomething();
}

2 个答案:

答案 0 :(得分:2)

过去我在一个单独的编译单元中实现了Dependency,并将其与原始编辑单元相关联。

Michael Feathers称之为Link Seam

答案 1 :(得分:2)

经过慎重考虑,我决定放弃这个想法。在给定测试场景的情况下,尝试和管理依赖应该使用特定实现(例如,真实,模拟,伪造)的环境变得太困难。

现在需要测试的所有依赖项都有接口,这些接口是无成员的。我的生产代码使用依赖指针,如果我想要可测试的代码,这是一个现实。在阅读了Roy Osherove的书 The Unit of Unit Testing 之后,我被说服了这个概念。我的常规构造函数实例化了真实的具体类。我还有额外的构造函数/ setter,它们有条件地编译用于单元测试,因此我可以使用存根/模拟来正确设置依赖项。

通过使用工具从类中提取接口,我减少了编写额外代码的需要。

总的来说,新设计很好,并且充分避免了以最小的开销模拟非指针成员变量的问题。