私有方法的unit testing
我正在编写一些unit testing的过程。 特别是我想testing一些私人方法。
到目前为止,我已经想出了使用。
#define private public
但是我对此并不满意,因为从unit testing的angular度来看,它会破坏所有的封装。
你用什么方法来unit testing私有方法。
如果方法足够复杂以保证孤立地进行testing,那么将它们重构成它们自己的类并且通过它们的公共接口进行testing。 然后在原class上私下使用它们。
在问题中你并没有提到讨厌的#define
hack,而是一个更清洁的机制,就是让testing成为被testing的类的朋友。 这允许testing代码(以及testing代码)访问私有,同时保护它们免受其他一切的影响。
但是,最好通过公共接口进行testing。 如果你的类X在私有成员函数中有很多代码,那么可能需要提取一个类X的实现所使用的新的类Y.然后这个新的类Y可以通过它的公共接口进行testing,而不会暴露它用于X类的客户。
如果您使用的是Googletesting,则可以使用FRIEND_TEST轻松地将testing装置声明为testing类的朋友。
而且你知道,如果testing私有函数像其他答案一样明显不好,那么它可能不会被内置到Googletesting中。
你可以阅读更多关于testing私人函数在这个答案中是好还是坏的。
将testing类作为原始类的朋友。 这个朋友声明将在#define UNIT_TEST
标志内。
class To_test_class { #ifdef UNIT_TEST friend test_class; #endif }
现在对于你的unit testing,你将用标志-DUNIT_TEST
编译代码。 这样你将能够testing私人function。
现在,您的unit testing代码将不会被推入生产环境,因为UNIT_TEST
标志将是错误的。 因此代码仍然是安全的。
你也不需要任何特殊的库来进行unit testing。
我知道这是一个较老的问题,但似乎没有人分享我喜欢的相对较好的方法,所以在这里:
将您希望testing的方法从private
更改为protected
。 对于其他类,这个方法仍然是private
,但是现在你可以从你的基类派生一个“testing”类,公开你想testing的私有function。
这是一个最小的例子:
class BASE_CLASS { protected: int your_method(int a, int b); }; class TEST_CLASS : public BASE_CLASS { public: int your_method(int a, int b) { return BASE_CLASS::your_method(a, b); } }
当然,你必须更新你的unit testing,以在派生类而不是基类上运行你的testing,但在此之后,对基类的任何改变都会自动反映到“testing”类中。
定义黑客是一个可怕的想法。 当你去编译它时,任意地用预处理器重写你的代码是不明智的。
现在已经有几个人提到,你是否应该testing私有方法是有争议的。 但是这并不包括你故意隐藏构造函数来限制实例化到某些范围或者其他一些更深奥的情况。
另外,你不能朋友的名字空间和“友谊”不是在C ++inheritance,所以根据你的unit testing框架,你可能会遇到麻烦。 幸运的是,如果您使用的是Boost.Test,那么可以通过Fixtures的forms来解决这个问题。
http://www.boost.org/doc/libs/1_52_0/libs/test/doc/html/utf/user-guide/fixture/per-test-case.html
你可以使用fixture来让它实例化你在unit testing函数中使用的所有实例,声明它们对于fixture和模块范围是静态的。 如果您使用的是名称空间,请不必担心,只需在名称空间内声明自己的fixture,然后在名称空间外声明自己的testing用例,然后使用作用域parsing运算符来获取静态成员。
BOOST_FIXTURE_TEST_CASE
macros将负责为你实例化和拆除你的灯具。
几个小时后,这就是我决定成为想要testing他们私人function的最佳解决scheme。 这是Max DeLiso和Miloš的结合 。
如果你使用boost :: unit-test,那么有一个简单而优雅的解决scheme。
-
在你的课堂中使用
protected
而不是private
的/* MyClass.hpp */ class MyClass { protected: int test() { return 1; } };
-
创build一个灯具 :
/* TestMyClass.cpp */ class F : public MyClass {}; BOOST_FIXTURE_TEST_SUITE(SomeTests, F) // use any protected methods inside your tests BOOST_AUTO_TEST_CASE(init_test) { BOOST_CHECK_EQUAL( test(), 1 ); } BOOST_AUTO_TEST_SUITE_END()
这样,您可以自由使用任何MyClass
function,而不需要#define private public
或将朋友添加到您的课程!
我不认为私人方法需要unit testing案例。
如果一个方法是私有的,它只能在该类中使用。 如果你已经使用这个私有方法testing了所有的公共方法,那么就不需要单独testing了,因为它只用于许多方面。