强制仅在某些代码中使用的特定构造函数,而不是其他任何地方

pep*_*ero 6 c++ unit-testing mocking c++11 access

有时,我们需要提供仅用于测试用途的特定构造函数.我们如何强制这样的构造函数仅用于测试代码,而不是其他任何地方.我只是想知道这是否可以在c ++ 11/14中实现.例如,

class A {
public: 
  A() = default; // used only in test code
}
class A_Test : public ::testing::Test {
 private:
  A a; // it is ok.
};
class A_Production {
 private:
  A a;  // compiler error
}
Run Code Online (Sandbox Code Playgroud)

我可以想象使用friend装饰器并将特定的构造函数放入protected限制访问.但遗留代码中还有其他现有的朋友.是否可以在c ++ 1x中创建类似受保护的自定义说明符?

有任何想法吗?

Sam*_*hik 1

我可以想出几种方法来做到这一点。

  1. 创建构造函数protected,只有测试子类使用它。

  2. 向某个虚拟类添加前向声明,class TestClassThatShouldNotBeUsedInProductionCode;然后声明一个将此类的引用作为参数的构造函数:

    A::A( /* other constructor arguments */,
          const TestClassThatShouldNotBeUsedInProductionCode &)
    
    Run Code Online (Sandbox Code Playgroud)

这个构造函数可以完全忽略这个参数。您的测试模块可以定义这个虚拟的空类:class TestClassThatShouldNotBeUsedInProductionCode {};,并能够A使用它构建您的类。那么,只有您的测试模块才能使用此构造函数,并且它的名称非常清楚其目的是什么。实际上没有任何方法可以将某些翻译单元定义为“真实”代码与“测试”代码,在 C++ 中,您只是想实现一个很难意外违反的明确策略。

有些变化是可能的,例如使用内部类而不是向前声明独立类。内部类只能由测试代码实例化。