有时,我们需要提供仅用于测试用途的特定构造函数。我们如何强制这样的构造函数仅用于测试代码,而不是其他任何地方。 我只是想知道这是否可以在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
}
我可以想象使用friend
装饰器并将特定构造函数放在protected
中以限制访问。但遗留代码中还有其他现有的朋友。是否可以在c ++ 1x中创建类似protected的自定义说明符?
任何想法?
答案 0 :(得分:3)
您可以使用Passkey Idiom:
您可以通过A
提供的A_Test
来限制ConstructorKey
对A
的访问权限,ConstructorKey
在其所需的界面中使用class A {
class ConstructorKey {
friend class A_Test;
private:
ConstructorKey() {};
ConstructorKey(ConstructorKey const&) = default;
};
public:
// Whoever can provide a key has access:
explicit A(ConstructorKey); // Used only in test code
};
class A_Test : public ::testing::Test {
private:
A a {ConstructorKey{}}; // OK
};
class A_Production {
private:
A a {ConstructorKey{}}; // Compiler error
};
,而不是直接友谊。 {{1}}的朋友可以访问。
{{1}}
答案 1 :(得分:1)
我可以想到几种方法。
创建构造函数protected
,只使用测试子类。
向某个虚拟类class TestClassThatShouldNotBeUsedInProductionCode;
添加前向声明,然后声明一个构造函数,该构造函数将此类的引用作为参数:
A::A( /* other constructor arguments */,
const TestClassThatShouldNotBeUsedInProductionCode &)
这个构造函数可以完全忽略这个参数。您的测试模块可以定义这个虚拟的空类:class TestClassThatShouldNotBeUsedInProductionCode {};
,并且能够使用它构建您的A
类。只有你的测试模块能够使用这个构造函数,然后,它的名称使得它的目的非常明确。没有任何方法可以将某些翻译单元定义为“真实”代码与“测试”代码,在C ++中,您只想实施一个难以意外违反的明确策略。
有些变体是可能的,例如使用内部类而不是前向声明独立类。内部类只能由测试代码实例化。
答案 2 :(得分:-1)
作为替代方案,在执行A:
测试的cpp文件中#define private public
#include "ClassA.h"
// ready for testing :)