花生先生richard

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

 

对于算法项目,基本都是被调用方,像mlr是以动态链接库的形式被isearch调用,那mlr模块暴露的公共接口是针对isearch,但对mlr的测试不仅仅是靠这些公共接口就够的,因为其本身的很多逻辑都是在私有的,这就需要我们有时候对其私有方法和成员进行测试。

下面有几种打开私有成员和方法的一些办法:

1.加宏编译

即在你需要打开私有的头文件中加入#define private public/protect

蛮暴力的,当然也是最容易操作和简单的。

2.利用Gtest的FRIEND_TEST()

Private class members are only accessible from within the class or by friends. To access a class' private members, you can declare your test fixture as a friend to the class and define accessors in your fixture. Tests using the fixture can then access the private members of your production class via the accessors in the fixture. Note that even though your fixture is a friend to your production class, your tests are not automatically friends to it, as they are technically defined in sub-classes of the fixture.

FRIEND_TEST(TestCaseName, TestName);

上面是gtest的关于私有成员测试wiki介绍,gtest会通过FRIEND_TEST(TestCaseName, TestName)声明了友元,即TestCaseName为友元类,而TestName为具体的case名。

下面用一个例子来简单说明下用法:

假如原类为:

clip_image001

在这个类中foo_e是私有函数,如何通过gtest对其进行测试呢?

对于被测代码,加入gtest相应的头文件和用FRIEND_TEST()来声明友元:

clip_image002

gtest测试代码:

clip_image003

对gtest有无fixture,这种方式都是适用的。另外需要注意gtest代码中TEST_F()后面跟的测试类和case名一定要和被测类中FRIEND_TEST()声明的一致,像上面的例子中FRIEND_TEST(ATest1,notfixture)和TEST(ATest1,notfixture)对应的。

缺点是:往被测代码中添加了测试代码;另外当你对私有成员测试的case很多时,就需要你在被测代码添加多个的FRIEND_TEST(),或者在你的测试代码中,把多个case放在一个TEST_F()中去。

优点是:对私有成员的打开和测试,代码使用规范,可读性好。即使版本升级,可以通过我们的测试代码中TEST_F()来打开被测代码相应的私有成员。

3、利用pimpl重构被测代码

Pimpl主要的作用是解开代码调用接口和具体实现的耦合,具体的实现大家有兴趣可以自己网上看下。利用这种方式打开私有成员,思路是先对被测代码按照pimpl模式进行重构,把具体实现的私有成员全部放到另外一个辅助类,通过指针访问实现的私有成员,然后对这个辅助类进行原类的私有成员测试。

原被测类:

clip_image004

重构后的MyClass为:

clip_image005

具体实现为:

clip_image006

经过上面的处理,我们调用新的MyClass类,就可以访问之前的私有成员了,My_Private_Method()对应原来的Private_Method(),My_Private_Class_method()对应原MyClass私有类Private_Class的method()。我们也就可以通过调用新的MyClass来访问其原私有成员,及对其测试了。

此方法原理简单,实现比较复杂。如果采用此方法,需要开发编码时就采用该模式,或者提测后人工的对其代码进行重构,工作量比较大。

posted on 2012-05-03 10:07  每天吃核桃  阅读(2380)  评论(2编辑  收藏  举报