Is it possible in Qt to unit test (access) private methods?
我正在为我的应用程序编写单元测试,现在我偶然发现了一个我应该测试私有方法的类。 这可能是特定班级设计不佳的结果,但我必须这样做。 有没有办法在Qt中调用私有方法,可能使用QMetaObject或类似的东西?
对于单元测试,我使用的是QTestLib框架。
正确的(读令人讨厌的)答案是你不应该测试私有方法,那些是实现细节
OTOH - 您是否考虑过有条件地声明它们是受保护的/私有的,这取决于您是在测试还是没有然后扩展?我过去常常用它来解决类似的问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #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,快速简便:使测试类成为公众的朋友。
1 2 3 4 5 | class Foo { // ... private: friend class FooTest; }; |
这样,您的
解决方案2,也称为正确完成:不要将私有方法放在公共类中,而是使用公共方法创建私有类。
1 2 3 4 5 6 | class Foo { // private: friend class FooPrivate; FooPrivate *d; }; |
1 2 3 4 5 6 | class FooPrivate { public: // only public stuff in here; // and especially this: static FooPrivate *get(Foo *f) { return f->d; } }; |
然后测试包括私有头,并调用
我不同意"私有成员是实现细节"的心态,在我看来,大致翻译为"仅测试代码的一部分"。
我可以参考"单位是单位"的论点,但为什么不尝试用尽可能多的代码覆盖你的代码,甚至内部单位呢?阿卡。给你的单位一个彻底的直肠检查。
考虑到这种形象,我经常使用的一种方法是在其他答案中没有提到的是执行以下操作:
注意:您必须小心依赖复杂实例化模式的类,以确保正确构造它们(读取:从子类ctor调用原始类的构造函数)。
我曾经读过Unit Test应该测试类的公共接口,而不是受保护/私有的东西。
你的班级应该从外面表现得很好。如果实施策略发生变化,您的Unit Test类仍然是相同的。
我找到了更方便的方法来做到这一点。首先,所有私有方法都应该是私有槽。
然后,您创建该类的实例:
1 | Foo a; |
然后我们可以使用QMetaObject :: invokeMethod来调用方法具有的任何插槽(公共或私有)。因此,如果我们想调用方法Test,我们可以这样做:
1 | QMetaObject::invokeMethod(&a,"Test", Qt::DirectConnection); |
此外,我们可以有返回值并发送参数......实际上,一切都在这里得到解答:http://doc.qt.nokia.com/stable/qmetaobject.html#invokeMethod