如何在Boost测试框架中测试类的私有成员方法?
Boost测试C++类私有成员的可行解决方案
方案1:直接声明Boost测试用例为友元
Boost.Test的宏展开后有固定结构,测试套件对应命名空间,测试用例对应该命名空间下的全局函数,无需自定义测试类即可直接声明友元:
- 在类头文件中前置声明测试用例函数,将其声明为类的友元:
// 前置声明测试用例所属命名空间与函数 namespace my_class_test_suite { void test_my_func(); } class MyClass { private: void myFunc(); // 声明对应测试用例为友元 friend void my_class_test_suite::test_my_func(); };
- 测试代码中定义对应名称的测试套件与用例即可直接访问私有成员:
BOOST_AUTO_TEST_SUITE(my_class_test_suite) BOOST_AUTO_TEST_CASE(test_my_func) { MyClass obj; obj.myFunc(); // 可正常调用私有方法 // 后续测试验证逻辑 } BOOST_AUTO_TEST_SUITE_END()
- 优点:实现简单,无需额外编写辅助代码
- 缺点:每个测试用例都需要单独添加友元声明,测试用例数量多的话维护成本较高
方案2:测试访问器类(推荐使用)
这是工业界最常用的私有成员测试方案,对生产代码的侵入性极低:
- 在MyClass头文件中仅声明一个空的测试访问器类为友元,不需要暴露任何内部逻辑:
class MyClass { private: void myFunc(); // 仅添加一行友元声明 friend class MyClassTestAccessor; };
- 测试代码中实现访问器类作为调用私有成员的中转,该类仅存在于测试编译单元,不会出现在生产代码中:
// 测试.cpp文件内实现,生产代码完全无感知 class MyClassTestAccessor { public: static void invoke_myFunc(MyClass& obj) { obj.myFunc(); } // 后续新增私有方法测试,仅需要在这里添加对应静态方法即可 }; BOOST_AUTO_TEST_CASE(test_my_func) { MyClass obj; MyClassTestAccessor::invoke_myFunc(obj); // 后续测试验证逻辑 }
- 优点:生产代码仅需添加一行友元声明,后续新增私有方法测试不需要修改生产代码头文件,不会对外暴露任何内部逻辑
- 缺点:需要编写少量测试辅助代码,复杂度极低
方案3:条件编译隔离测试入口
如果完全不想在生产代码中添加测试相关的友元声明,可以用条件编译做隔离:
class MyClass { private: void myFunc(); // 仅在单元测试编译阶段可见 #ifdef UNIT_TEST public: void test_myFunc() { myFunc(); } // 也可以直接将myFunc的访问权限放在该条件块中改为public #endif };
编译测试代码时添加-DUNIT_TEST编译参数即可调用测试入口,生产编译时不定义该宏,所有测试相关代码不会被编译进生产二进制。
- 优点:生产运行环境完全无任何测试相关代码残留
- 缺点:头文件中会存在测试相关代码块,需要团队统一约定条件编译宏的使用规范,避免生产逻辑误写在条件块中
内容的提问来源于stack exchange,提问作者Tyler Shellberg
相关产品推荐
相关产品推荐

