我看到很多疯狂的方法可以在单元测试时访问私有变量。我见过的最令人兴奋的是#define private public
。
但是,我从未见过有人建议在编译器级别关闭私有变量。我一直以为你不能。我向许多开发人员抱怨说,如果你能告诉编译器为这个文件退出,那么单元测试就会容易得多。
然后我偶然发现-fno-access-control gcc编译器选项。这显然是单元测试的完美方式。您的原始源文件未经修改,没有为单元测试注入的朋友,没有使用奇怪的预处理器魔法重新编译。在编译单元测试时,只需轻按“无访问控制”开关即可。
我错过了什么吗?这是我希望它是测试银弹的单位吗?
我看到的唯一缺点是该技术的gcc特性。但是,我假设MSVS有一个类似的标志。
答案 0 :(得分:6)
我认为单元测试不需要访问私有成员。
通常,单元测试用于测试类的接口,而不是内部实现。这样,如果界面被破坏,对内部的更改只会破坏测试。
查看我的answer类似的问题以及随后的讨论。可以肯定的是,这是一个有争议的话题,但这是我的0.02美元。
答案 1 :(得分:2)
我通常尝试在单元测试中仅使用我的类的公共接口。测试驱动开发/设计在这里有很多帮助,因为结果类倾向于启用这种单元测试。
但是,有时您需要让单元测试访问非公共成员,例如用Fake实例替换Singleton的内容。为此,我使用Java中的包保护和C ++中的朋友。
有些人似乎向后弯腰以避开朋友,但他们应该在适当时使用,并且他们的使用不会影响设计。它们也是声明性的,让其他程序员知道你在做什么。
答案 2 :(得分:1)
我担心它不会因为我的单元测试需要访问其他动态库(.so文件)中构建的类的私有成员,但这正是我需要的。
我只需要在单元测试中声明标志。所以编译(每个测试都是.so)。甚至没有定义被访问对象的库。
我需要它来访问表单上的内部小部件来填充它们的值;它们对程序的其余部分不可见,但如果我的测试是代表用户输入输入则需要它们。我以为我会为那些私人访问反对者分享一个用例:)
同样为了完整性,这是我的表单类,显示私有name_字段:
struct EditProduct : public widgets::BusinessObjForm<model::Product> {
public:
EditProduct (WContainerWidget *parent=0);
protected:
void fillObjFields();
private:
// Consts
static const double minPrice = 0.0;
static const double maxPrice = 10000.0;
// Fields
WLineEdit* name_;
WTextEdit* description_;
WSpinBox* price_;
WFileUpload* image_;
// Methods
bool validate();
void saveProduct(const WString& message);
};
这是访问该小部件的单元测试的开始:
BOOST_AUTO_TEST_CASE( form_save_test )
{
EditProduct form(app.root());
string txt = "this is a product";
form.name_->setText(txt);
BOOST_CHECK_EQUAL(form.name_->text(), txt);
}
答案 3 :(得分:-2)
Yeap,相当有用的GCC选项,但MSVC没有任何类似的东西 我们使用宏来代替:
#define class struct
#define private public
#define protected public
^ _ ^