以前测试类访问被测类的私有、保护成员的方法是在被测类中声明测试类为它的友元类,这种方法有一个很不好的缺陷:需要修改正式代码。
本方案便是解决此问题的。此方案的思想是包向信原创,之后又与陈国栋讨论,解决了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同样还是存在访问权限方面的问题,只是出错范围缩小了些。
所以这种方法暂时没有正式采用,供参考。