如何用 FRIEND_TEST 在 GoogleTest 中测试 C++ 类的私有成员
如何用 FRIEND_TEST 在 GoogleTest 中测试 C 类的私有成员【免费下载链接】googletestGoogleTest - Google Testing and Mocking Framework项目地址: https://gitcode.com/GitHub_Trending/go/googletest当被测类的关键逻辑位于private或protected区域而你又确实在用 GoogleTest 编写单元测试时直接调用私有成员会编译失败。GoogleTest 提供的FRIEND_TEST宏就是为此设计的在类的定义体内声明一条宏把某个具体的TEST或TEST_F实例声明为该类的友元这个测试就能访问该类的私有成员。本文基于 GoogleTest 仓库文档和测试代码给出从声明到编译运行的完整操作路径。适用前提支持 C17 的 C 编译器、CMake 与 GoogleTest下文用 CMake 的FetchContent方式引入。理解 FRIEND_TEST 宏的实际作用宏的定义在 gtest_prod.h 中#define FRIEND_TEST(test_case_name, test_name) \ friend class test_case_name##_##test_name##_Test它把参数拼接成 GoogleTest 内部为测试生成的类名并声明为friend class。因此宏必须写在被测类的类体内部通常在private:区域它针对的是某一个具体测试TestSuiteNameTestName的组合而不是整个测试类所以每要放行一个测试就要多写一条FRIEND_TEST使用 fixture 的TEST_F同样适用因为 GoogleTest 会为TEST_F生成对应的测试类友元声明对生成的类生效。注意这个头文件是为生产代码准备的被测类的头文件里#include gtest/gtest_prod.h即可测试文件本身包含gtest/gtest.h。在被测类中声明友元测试仓库自带的测试 production.h 展示了一个完整的被测试类覆盖了不带 fixture 和带 fixture 两种写法#include gtest/gtest_prod.h class PrivateCode { public: // Declares a friend test that does not use a fixture. FRIEND_TEST(PrivateCodeTest, CanAccessPrivateMembers); // Declares a friend test that uses a fixture. FRIEND_TEST(PrivateCodeFixtureTest, CanAccessPrivateMembers); PrivateCode(); int x() const { return x_; } private: void set_x(int an_x) { x_ an_x; } int x_; };两条宏分别放行一个普通TEST和一个TEST_F被放行的测试都能访问私有的set_x()和成员变量x_。编写访问私有成员的测试对应上面的类gtest_prod_test.cc 展示了两种测试的写法#include production.h #include gtest/gtest.h // Tests that private members can be accessed from a TEST declared as // a friend of the class. TEST(PrivateCodeTest, CanAccessPrivateMembers) { PrivateCode a; EXPECT_EQ(0, a.x_); a.set_x(1); EXPECT_EQ(1, a.x_); } typedef testing::Test PrivateCodeFixtureTest; // Tests that private members can be accessed from a TEST_F declared // as a friend of the class. TEST_F(PrivateCodeFixtureTest, CanAccessPrivateMembers) { PrivateCode a; EXPECT_EQ(0, a.x_); a.set_x(2); EXPECT_EQ(2, a.x_); }两个要点FRIEND_TEST(TestSuiteName, TestName)中的两个参数必须和TEST/TEST_F的宏参数一一对应拼错任何一处友元声明就会失配编译时报private访问错误。TEST_F需要一个 fixture 类型。仓库示例直接用typedef testing::Test PrivateCodeFixtureTest;满足这一点如果你有自己的 fixture 类把它定义成和测试同名的类即可。命名空间限制测试必须与被测类同命名空间这是文档中特别强调的约束。如果被测类定义在某个命名空间内要让测试成为友元fixture 和测试必须定义在完全相同的命名空间里不能是匿名命名空间或 inline 命名空间gtest_prod.h 的注释和 reference/testing.md 的FRIEND_TEST条目都指出了这一点。文档给出的示例namespace my_namespace { class MyClass { friend class MyClassTest; FRIEND_TEST(MyClassTest, HasPropertyA); FRIEND_TEST(MyClassTest, HasPropertyB); ... definition of class MyClass ... }; } // namespace my_namespace对应的测试代码必须写成namespace my_namespace { class MyClassTest : public testing::Test { ... }; TEST_F(MyClassTest, HasPropertyA) { ... } TEST_F(MyClassTest, HasPropertyB) { ... } } // namespace my_namespace如果你的生产类在默认命名空间像上面的PrivateCode则测试直接写在文件作用域即可不需要额外包一层 namespace。用 CMake 构建并运行验证按 docs/quickstart-cmake.md 的方式组织工程。项目目录下的CMakeLists.txtcmake_minimum_required(VERSION 3.14) project(my_project) # GoogleTest requires at least C17 set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) include(FetchContent) FetchContent_Declare( googletest URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip ) # For Windows: Prevent overriding the parent projects compiler/linker settings set(gtest_force_shared_crt ON CACHE BOOL FORCE) FetchContent_MakeAvailable(googletest) enable_testing() add_executable( production_test production.h gtest_prod_test.cc ) target_link_libraries( production_test GTest::gtest_main ) include(GoogleTest) gtest_discover_tests(production_test)其中FetchContent_Declare的 URL 是 quickstart 文档原样给出的地址commit hash03597a01ee50ed33e9dfd640b249b4be3799d395对应文档推荐的 GoogleTest 版本Windows 平台的gtest_force_shared_crt设置仅在 Windows 上需要。测试源文件按上一步的代码放入项目目录。然后在项目目录执行cmake -S . -B build cmake --build build cd build ctest运行成功时文档展示的 ctest 输出形如文档示例实际路径和耗时会有差异Test project .../my_project/build Start 1: PrivateCodeTest.CanAccessPrivateMembers 1/2 Test #1: PrivateCodeTest.CanAccessPrivateMembers ... Passed 2/2 Test #2: PrivateCodeFixtureTest.CanAccessPrivateMembers ... Passed 100% tests passed, 0 tests failed out of 2判断方式两条测试都Passed说明友元声明生效、私有成员访问被编译器放行且断言成立如果编译阶段就报私有成员访问错误检查FRIEND_TEST的两个参数是否与TEST/TEST_F完全一致、以及命名空间是否对齐。限制与替代路径docs/advanced.md 的 Testing Private Code 一节先给出了立场按黑盒测试原则大多数时候应通过公共接口测试如果频繁需要测试内部实现文档建议先考虑把实现拆到独立的实现类中再测试。因此FRIEND_TEST适合确实必须的场景文档同时给出两条替代路径fixture 友元 accessor把测试 fixture 声明为被测类的友元在 fixture 里定义访问器TEST_F通过访问器读取私有成员。注意 fixture 是友元并不自动让子测试类成为友元这正是FRIEND_TEST存在的意义。*-internal.h实现类把私有逻辑重构进实现类声明放在*-internal.h生产代码和测试可以包含该头文件外部客户端不可以。参考位置宏定义gtest_prod.h完整示例生产类 测试production.h、gtest_prod_test.cc私有代码测试原则与替代方案docs/advanced.md宏参考条目docs/reference/testing.mdCMake 构建流程docs/quickstart-cmake.md【免费下载链接】googletestGoogleTest - Google Testing and Mocking Framework项目地址: https://gitcode.com/GitHub_Trending/go/googletest创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

AI SDK Provider 模型 ID 维护指南:在 TypeScript AI 工具库中安全新增与移除模型

AI SDK Provider 模型 ID 维护指南:在 TypeScript AI 工具库中安全新增与移除模型

AI SDK Provider 模型 ID 维护指南:在 TypeScript AI 工具库中安全新增与移除模型 【免费下载链接】ai The AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and agents…

2026/9/15 20:08:01 阅读更多 →
MATLAB三参数威布尔分布估计:位置参数网格搜索与极大似然实现

MATLAB三参数威布尔分布估计:位置参数网格搜索与极大似然实现

简介:面向开展威布尔分布估计与三参数评估教学研究的本硕博学生,这套MATLAB资源包提供核心算法脚本、配套使用说明与操作录像,适合算法编程学习、课程设计和教研参考。资源压缩为rar格式,共3个文件,包含一个m脚本、一个…

2026/9/18 22:33:31 阅读更多 →
SadTalker:3条命令让单张静态图开口说话

SadTalker:3条命令让单张静态图开口说话

SadTalker:3条命令让单张静态图开口说话 【免费下载链接】SadTalker [CVPR 2023] SadTalker:Learning Realistic 3D Motion Coefficients for Stylized Audio-Driven Single Image Talking Face Animation 项目地址: https://gitcode.com/GitHub_Trend…

2026/9/18 8:49:46 阅读更多 →

最新新闻

Naive UI 创建适配主题的自定义组件:n-config-provider、n-element 与 useThemeVars 全面指南

Naive UI 创建适配主题的自定义组件:n-config-provider、n-element 与 useThemeVars 全面指南

前端UI组件 【免费下载链接】naive-ui A Vue 3 Component Library. Fairly Complete. Theme Customizable. Uses TypeScript. Fast. 项目地址: https://gitcode.com/gh_mirrors/na/naive-ui 点击查看 免费下载 Naive UI 不仅内置了数十个开箱即用的主题化组件&…

2026/9/21 3:45:05 阅读更多 →
如何给SumatraPDF贡献代码?从构建、调试到提交PR的完整开发者指南

如何给SumatraPDF贡献代码?从构建、调试到提交PR的完整开发者指南

如何给SumatraPDF贡献代码?从构建、调试到提交PR的完整开发者指南 【免费下载链接】sumatrapdf SumatraPDF reader 项目地址: https://gitcode.com/gh_mirrors/su/sumatrapdf SumatraPDF 是一款免费的开源多格式文档阅读器(支持 PDF、EPUB、MOBI、…

2026/9/21 3:44:04 阅读更多 →
Readest OPDS 分组轮播实现解析:基于 react-virtuoso 的虚拟化横向卡片滑轨与懒加载封面

Readest OPDS 分组轮播实现解析:基于 react-virtuoso 的虚拟化横向卡片滑轨与懒加载封面

桌面应用跨平台前端 【免费下载链接】readest Readest is a modern, feature-rich ebook reader designed for avid readers offering seamless cross-platform access, powerful tools, and an intuitive interface to elevate your reading experience. 项目地址:…

2026/9/21 3:43:04 阅读更多 →
使用 Go 标准库 time 正确处理时间:Uber Go Style Guide 时间处理实践全解析

使用 Go 标准库 time 正确处理时间:Uber Go Style Guide 时间处理实践全解析

文档教程代码质量Lint 【免费下载链接】guide The Uber Go Style Guide. 项目地址: https://gitcode.com/gh_mirrors/gu/guide 点击查看 免费下载 导读 时间处理是 Go 开发中最容易被低估的复杂度来源——"一天有 24 小时""一小时有 60 分钟"…

2026/9/21 3:43:04 阅读更多 →
Toonflow是什么?AI短剧工厂完整指南:2小时把小说变成成片,创作效率提升10倍

Toonflow是什么?AI短剧工厂完整指南:2小时把小说变成成片,创作效率提升10倍

Toonflow是什么?AI短剧工厂完整指南:2小时把小说变成成片,创作效率提升10倍 【免费下载链接】Toonflow-app Toonflow 是一款 AI 短剧漫剧工具,能够利用 AI 技术将小说自动转化为剧本,并结合 AI 生成的图片和视频&#…

2026/9/21 3:42:03 阅读更多 →
Macrotrends 历史金融数据提取实战:基于 browser-harness 的四种无浏览器抓取模式

Macrotrends 历史金融数据提取实战:基于 browser-harness 的四种无浏览器抓取模式

Macrotrends 历史金融数据提取实战:基于 browser-harness 的四种无浏览器抓取模式 【免费下载链接】browser-harness Browser Harness | Self-healing harness that enables LLMs to complete any task. 项目地址: https://gitcode.com/gh_mirrors/br/browser-har…

2026/9/21 3:42:03 阅读更多 →

日新闻

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程 【免费下载链接】agentic-awesome-skills AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and …

2026/9/21 0:00:01 阅读更多 →
gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析 【免费下载链接】gin-vue-admin 🚀ViteVue3Gin拥有AI辅助的基础开发平台,企业级业务AI开发解决方案,内置mcp辅助服务,内置skills管理,…

2026/9/21 0:00:01 阅读更多 →
Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

桌面应用AI 应用插件系统 【免费下载链接】Wox A cross-platform launcher that simply works 项目地址: https://gitcode.com/gh_mirrors/wo/Wox 点击查看 免费下载 全功能插件(Full-featured Plugin)是 Wox 三类插件实现方式中能力最完整的…

2026/9/21 0:00:01 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/21 3:13:20 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/21 2:19:36 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/20 0:00:46 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/19 23:01:36 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/19 17:50:38 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →