CppUnit用例访问被测类私有&保护成员的解决方案
2009-10-20 18:54
411 查看
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宏也可以)
![](http://sinojelly.blog.51cto.com/attachment/200910/20/479153_1256036073CcGJ.jpg)
3.2. 如果采用了库链接方式,库的工程中需要定义private=protected。 如果不做这个定义,会有链接错误,因为编译库的时候某些静态成员被识别为private访问权限,而CppUnit工程链接的时候要链接protected访问权限的函数,就出现了链接不过的问题。(非静态成员不是采用的静态链接方式,没有此问题)
通过修改库的工程,把private通过宏定义方式改成protected,解决了这个问题,同时没有修改源代码。
![](http://sinojelly.blog.51cto.com/attachment/200910/20/479153_12560360788dOM.jpg)
注意: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. 使用辅助工具宏定义中间类和测试类。 测试代码中每处用到被测类的地方都要用中间类。
![](http://sinojelly.blog.51cto.com/attachment/200910/20/479153_1256036083gQmU.jpg)
建议把上述的测试类定义放到cpp文件,即测试用例不再用h文件,这样文件结构更简单。
4. 注意事项 1、 如果被测类是模板类,则不能用这种方法(它不能指定模板参数)。
2、 如果中间类需要提供构造函数或者其它内容,则需要自己定义中间类和测试类,命名规则符合工具宏的规则,即中间类名是被测类名加Temp构成,测试类名是被测类名加Test构成。
5. 其它方案 只有一句话:在所有工程的编译选项中增加宏定义:private=public、protected=public,如果需要访问默认权限的成员,可再定义class=struct。
优点:
(1) 简单,直接测试被测类。
(2) 能够解决模板私有成员访问问题。
缺点:
(1) 访问权限完全失效。
(2) 一些访问权限相关的问题,本来在编译期可以发现的,将无法发现。(当然一般不会引起运行错误。)
实际上,上面说到的方案是对这种方案的改进,但没能从实质上解决访问权限的问题,把private定义为protected同样还是存在访问权限方面的问题,只是出错范围缩小了些。
所以这种方法暂时没有正式采用,供参考。
本方案便是解决此问题的。此方案的思想是包向信原创,之后又与陈国栋讨论,解决了private成员访问问题、使用链接库时的静态成员链接问题,最后再整理出来的易于操作的实施办法。
注:如果您对访问权限不关心,可以直接参见“其它方案”中提供的更加简单、有效的解决方案。
2. 方案简述 1) 从被测类(CBeTested)派生出用于测试的中间类(CBeTestedTemp)。
2) 在中间类(CBeTestedTemp)中声明测试类(CBeTestedTest)为它的友元类。
3) 测试类(CBeTestedTest)通过测试中间类(CBeTestedTemp)来间接的测试被测类(CBeTested)。
3. 实施办法 3.1. 改变被测类的private关键字为protected。 在CppUnit的stdafx.h中包含被测类头文件之前把private通过宏定义为protected,以便访问被测类中的私有成员:(工程中定义private=protected宏也可以)
![](http://sinojelly.blog.51cto.com/attachment/200910/20/479153_1256036073CcGJ.jpg)
3.2. 如果采用了库链接方式,库的工程中需要定义private=protected。 如果不做这个定义,会有链接错误,因为编译库的时候某些静态成员被识别为private访问权限,而CppUnit工程链接的时候要链接protected访问权限的函数,就出现了链接不过的问题。(非静态成员不是采用的静态链接方式,没有此问题)
通过修改库的工程,把private通过宏定义方式改成protected,解决了这个问题,同时没有修改源代码。
![](http://sinojelly.blog.51cto.com/attachment/200910/20/479153_12560360788dOM.jpg)
注意: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. 使用辅助工具宏定义中间类和测试类。 测试代码中每处用到被测类的地方都要用中间类。
![](http://sinojelly.blog.51cto.com/attachment/200910/20/479153_1256036083gQmU.jpg)
建议把上述的测试类定义放到cpp文件,即测试用例不再用h文件,这样文件结构更简单。
4. 注意事项 1、 如果被测类是模板类,则不能用这种方法(它不能指定模板参数)。
2、 如果中间类需要提供构造函数或者其它内容,则需要自己定义中间类和测试类,命名规则符合工具宏的规则,即中间类名是被测类名加Temp构成,测试类名是被测类名加Test构成。
5. 其它方案 只有一句话:在所有工程的编译选项中增加宏定义:private=public、protected=public,如果需要访问默认权限的成员,可再定义class=struct。
优点:
(1) 简单,直接测试被测类。
(2) 能够解决模板私有成员访问问题。
缺点:
(1) 访问权限完全失效。
(2) 一些访问权限相关的问题,本来在编译期可以发现的,将无法发现。(当然一般不会引起运行错误。)
实际上,上面说到的方案是对这种方案的改进,但没能从实质上解决访问权限的问题,把private定义为protected同样还是存在访问权限方面的问题,只是出错范围缩小了些。
所以这种方法暂时没有正式采用,供参考。
相关文章推荐
- CppUnit用例访问被测类私有&保护成员的解决方案
- 三十八、继承与派生:派生类对基类成员的访问控制之保护继承与私有继承
- C++ 公有继承、保护继承和私有继承中类成员的访问权限的控制
- 通过反射访问对象私有和保护成员
- 通过反射访问对象私有和保护成员
- .NET程序内,访问私有或者保护成员的技巧
- C++ 公有继承、保护继承和私有继承中类成员的访问权限的控制
- 第3周课后实践·阅读程序(2)-利用指针访问私有数据成员
- C++类访问另一个类的私有成员和保护成员
- 3第一周课后练习·阅读计划(2)-使用指针来访问私有数据成员
- C++基类和派生类私有、保护、公有成员访问控制以及动态绑定、三种继承
- .NET程序内,访问私有或者保护成员的技巧
- 3第一周课后练习·阅读计划(3)-使用函数来访问私有数据成员
- 第3周课后实践·阅读程序(3)-利用函数访问私有数据成员
- C++ 公有继承、保护继承和私有继承中类成员的访问权限的控制
- 第3周课后实践·程序阅读(4)-利用引用访问私有数据成员
- C++ 公有继承、保护继承和私有继承中类成员的访问权限的控制
- C++ 公有继承、保护继承和私有继承中类成员的访问权限的控制
- bool operator==(fun &a){if(this->a==a.a&&this->b==a.b)//为什么a.a可以访问a的私有成员
- C++编程中私有和保护以及公有的类成员访问控制