如何在GoogleTest中测试多继承场景下的protected成员
访问报错的核心原因
你的代码有两个认知误区,直接触发了protected权限校验失败:
- 模板实例是完全独立的类型:
myTestUT继承的是Foo<Bar>,而Bar继承的是Foo<int>,这两个是Foo模板生成的完全无关的两个类,不存在继承关系上的交集,你继承Foo<Bar>根本碰不到Bar内部来自Foo<int>的成员。 - protected权限的访问规则本身就不支持跨实例访问:就算你把
myTestUT的继承改成public Foo<int>,你也只能访问myTestUT自身实例里继承到的mMember,不能直接访问一个独立的Bar实例里的mMember——C++标准规定,派生类对基类protected成员的访问权限,仅限定于自身继承的基类子对象部分,无权访问其他同类型基类/派生类实例的protected成员。
可行的测试实现方案
以下两种是GoogleTest场景下测试protected成员的标准做法,不需要修改生产代码的核心逻辑:
- 方案1:使用友元声明开权限(官方推荐)
这是侵入性最低的官方方案,只需要在基类里给测试固件加友元声明,不需要调整测试逻辑:#include <gtest/gtest.h> template <typename T> class Foo { public: int set() { mMember=1; } protected: int mMember; private: // 前置声明测试固件后声明友元,测试代码即可访问protected成员 friend class myTestUT; }; class Bar : public Foo<int> {}; namespace { // 不需要再错误继承Foo<Bar>,测试固件只需要继承testing::Test即可 class myTestUT : public testing::Test { }; TEST_F(myTestUT, how_can_i_test_this){ Bar bar; bar.set(); ASSERT_EQ(bar.mMember, 1); // 友元权限下可直接访问,无编译错误 } } - 方案2:测试专用派生类暴露成员(零侵入生产代码)
如果你不想给生产代码加任何测试相关的友元声明,可以在测试文件里定义一个测试专用的派生类,通过using声明把需要访问的protected成员提升为public访问权限,测试时使用这个派生类即可:// 测试专用类放在匿名命名空间,不会污染生产代码符号 namespace { class TestableBar : public Bar { public: // 把基类的protected mMember提升为public using Foo<int>::mMember; }; class myTestUT : public testing::Test { }; TEST_F(myTestUT, how_can_i_test_this){ TestableBar bar; bar.set(); ASSERT_EQ(bar.mMember, 1); // 直接访问public成员,无权限问题 } }
注意:你之前尝试的多继承当访问桥梁的思路不可行,本质是混淆了模板实例的独立性和protected访问权限的作用边界,不需要在这个方向上继续调试。
内容的提问来源于stack exchange,提问作者waas1919
相关产品推荐
相关产品推荐

