CppUnit用例访问被测类私有&保护成员的解决方案

来源:互联网 发布:rds阿里云 编辑:程序博客网 时间:2024/06/06 16:50

1. 方案意义
以前测试类访问被测类的私有、保护成员的方法是在被测类中声明测试类为它的友元类,这种方法有一个很不好的缺陷:需要修改正式代码。

本方案便是解决此问题的。此方案的思想是包向信原创,之后又与陈国栋讨论,解决了private成员访问问题、使用链接库时的静态成员链接问题,最后再整理出来的易于操作的实施办法。

注:如果您对访问权限不关心,可以直接参见“其它方案”中提供的更加简单、有效的解决方案。

2. 方案简述
1) 从被测类(CBeTested)派生出用于测试的中间类(CBeTestedTemp)。

2) 在中间类(CBeTestedTemp)中声明测试类(CBeTestedTest)为它的友元类。

3) 测试类(CBeTestedTest)通过测试中间类(CBeTestedTemp)来间接的测试被测类(CBeTested)。

3. 实施办法 3.1. 改变被测类的private关键字为protected。
在CppUnit的stdafx.h中包含被测类头文件之前把private通过宏定义为protected,以便访问被测类中的私有成员:(工程中定义private=protected宏也可以)

 

3.2. 如果采用了库链接方式,库的工程中需要定义private=protected。
如果不做这个定义,会有链接错误,因为编译库的时候某些静态成员被识别为private访问权限,而CppUnit工程链接的时候要链接protected访问权限的函数,就出现了链接不过的问题。(非静态成员不是采用的静态链接方式,没有此问题)

通过修改库的工程,把private通过宏定义方式改成protected,解决了这个问题,同时没有修改源代码。

 

注意:CBRI工程也需要增加此宏定义,否则链接不过。

上述3.1/3.2也可以汇总为一句话,在所有工程中定义private=protected。

3.3. 在CppUnit工程的StdAfx.h中定义辅助工具宏。
#define DEFINE_TEMPTEST_CLASS(theClass) /

class theClass##Temp : public theClass /

{/

friend class theClass##Test;/

};/

class theClass##Test : public CPPUNIT_NS::TestFixture

3.4. 使用辅助工具宏定义中间类和测试类。
测试代码中每处用到被测类的地方都要用中间类。

 

建议把上述的测试类定义放到cpp文件,即测试用例不再用h文件,这样文件结构更简单。

4. 注意事项
1、 如果被测类是模板类,则不能用这种方法(它不能指定模板参数)。

2、 如果中间类需要提供构造函数或者其它内容,则需要自己定义中间类和测试类,命名规则符合工具宏的规则,即中间类名是被测类名加Temp构成,测试类名是被测类名加Test构成。

5. 其它方案
只有一句话:在所有工程的编译选项中增加宏定义:private=public、protected=public,如果需要访问默认权限的成员,可再定义class=struct。

优点:

(1) 简单,直接测试被测类。

(2) 能够解决模板私有成员访问问题。

缺点:

(1) 访问权限完全失效。

(2) 一些访问权限相关的问题,本来在编译期可以发现的,将无法发现。(当然一般不会引起运行错误。)

实际上,上面说到的方案是对这种方案的改进,但没能从实质上解决访问权限的问题,把private定义为protected同样还是存在访问权限方面的问题,只是出错范围缩小了些。

所以这种方法暂时没有正式采用,供参考。
文章出处:飞诺网(www.firnow.com):http://dev.firnow.com/course/3_program/c/cshl/20100710/395410.html#comment