我正在为我的应用程序编写单元测试,现在我偶然发现了一个我应该测试私有方法的类。这可能是特定班级设计不佳的结果,但我必须这样做。有没有办法在Qt中调用私有方法,可能使用QMetaObject或类似的东西?
对于单元测试,我使用的是QTestLib框架。
答案 0 :(得分:5)
正确(阅读烦人)的答案是你不应该测试私有方法,这些是实现细节;-)
。
OTOH - 您是否考虑过有条件地声明它们是受保护的/私有的,具体取决于您是否正在测试或不进行扩展?我过去常常用它来解决类似的问题。
#ifdef TESTING
// or maybe even public!
#define ACCESS protected
#else
#define ACCESS private
#endif
/* your class here */
class Foo {
ACCESS
int fooeyness;
}
// or better yet, place this in a different file!
#ifdef TESTING
/*
class which extends the tested class which has public accessors
*/
#endif
答案 1 :(得分:2)
解决方案1,快速简便:让测试类成为公众的朋友。
class Foo {
// ...
private:
friend class FooTest;
};
这样,您的FooTest
类可以访问公共类的所有成员。但是,这样您每次要从不同的测试中访问私有数据时都需要修改原始类,并且在公共API中泄漏有关测试的信息,并且您可能会打开类命名冲突(如果有/另一个/ FooTest类?),等等。
解决方案2,又称正确完成:不要将私有方法放在公共类中,而是使用公共方法创建私有类。
class Foo {
//
private:
friend class FooPrivate;
FooPrivate *d;
};
FooPrivate
在其自己的标头中声明,该标头可能未安装,或保留在include-privates /子目录中,或者其他任何内容 - 即它不会被正常使用。公共班级保持干净。
class FooPrivate {
public:
// only public stuff in here;
// and especially this:
static FooPrivate *get(Foo *f) { return f->d; }
};
然后测试包括私有标头并调用FooPrivate::get(fooObj)
来获取私有类实例,然后愉快地使用它。
答案 2 :(得分:1)
我不同意“私人成员是实施细节”的心态,在我看来,大致翻译为“只测试部分代码”。
我可以说“单位是单位”这个论点,但是为什么不尝试用尽可能多的代码覆盖你的代码,即使是在单位内?阿卡。 为您的单位提供彻底的直肠检查。
考虑到这一点,我经常使用的一种方法是在其他答案中没有提及的是:
protected
而不是private
进行测试的成员。注意:您必须小心依赖复杂实例化模式的类,以确保正确构造它们(读取:从子类ctor调用原始类的构造函数)。
答案 3 :(得分:0)
我找到了更方便的方法来做到这一点。首先,所有私有方法都应该是私有槽。 然后创建类的实例:
Foo a;
然后我们可以使用QMetaObject :: invokeMethod来调用方法具有的任何插槽(公共或私有)。因此,如果我们想调用方法Test,我们可以这样做:
QMetaObject::invokeMethod(&a, "Test", Qt::DirectConnection);
此外,我们可以有返回值并发送参数......实际上,所有内容都在这里得到解答:http://doc.qt.nokia.com/stable/qmetaobject.html#invokeMethod
答案 4 :(得分:0)
我曾经读过Unit Test应该测试类的公共接口,而不是受保护/私有的东西。
你的班级应该从外面表现得很好。如果实施策略发生变化,您的单元测试类仍然是相同的。