使用-fno-access-control进行单元测试

时间:2009-05-13 23:29:36

标签: c++ unit-testing gcc

我看到很多疯狂的方法可以在单元测试时访问私有变量。我见过的最令人兴奋的是#define private public

但是,我从未见过有人建议在编译器级别关闭私有变量。我一直以为你不能。我向许多开发人员抱怨说,如果你能告诉编译器为这个文件退出,那么单元测试就会容易得多。

然后我偶然发现-fno-access-control gcc编译器选项。这显然是单元测试的完美方式。您的原始源文件未经修改,没有为单元测试注入的朋友,没有使用奇怪的预处理器魔法重新编译。在编译单元测试时,只需轻按“无访问控制”开关即可。

我错过了什么吗?这是我希望它是测试银弹的单位吗?

我看到的唯一缺点是该技术的gcc特性。但是,我假设MSVS有一个类似的标志。

4 个答案:

答案 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

^ _ ^

相关问题