当前位置: 首页 > ai >正文

【C/C++】gmock vs mockcpp

文章目录

  • gmock vs mockcpp
    • 1 基本介绍
    • 2 语法风格与使用方式
      • gmock 特点(基于接口 Mock):
      • mockcpp 特点(基于重写/拦截原函数):
    • 3 对比总结
    • 4 实际使用建议

gmock vs mockcpp

gmockmockcpp 是 C++ 中常用的两个 Mock 框架,用于单元测试时模拟对象或函数的行为。

它们的核心目标相似:使测试更加隔离、可控与可验证,但两者在设计理念、使用方式、语法风格、兼容性等方面存在明显差异。


1 基本介绍

项目gmock(Google Mock)mockcpp
作者Google东南大学(何海涛等)
语言C++(与 gtest 紧密集成)C++
发布时间2008 年左右2006 年左右
依赖Google Test (gtest)无需 gtest,可与其它测试框架搭配

2 语法风格与使用方式

gmock 特点(基于接口 Mock):

  • 基于接口/抽象类设计(需要提前设计好虚函数接口)
  • 使用宏定义 MOCK_METHOD() 快速生成 Mock 函数
  • 测试语句直观如:EXPECT_CALL(mockObj, Foo()).Times(1);
  • 支持匹配器(_, Eq(x), AnyOf, AllOf 等)
  • 语法现代、类型安全,支持 C++11+
class ICalc {
public:virtual int Add(int a, int b) = 0;virtual ~ICalc() = default;
};class MockCalc : public ICalc {
public:MOCK_METHOD(int, Add, (int a, int b), (override));
};TEST(MyTest, Addition) {MockCalc calc;EXPECT_CALL(calc, Add(1, 2)).WillOnce(Return(3));ASSERT_EQ(calc.Add(1, 2), 3);
}

mockcpp 特点(基于重写/拦截原函数):

  • 不依赖接口或虚函数,可以对 非虚函数/全局函数/静态函数 进行 Mock
  • 使用 MOCKER(methodName).stubs().will(returnValue()); 风格
  • 内部使用函数地址重写、hook 技术等实现原函数替换
  • 支持打桩(Stub)与调用验证
  • 适合 legacy code(老代码)测试,不易侵入原设计
class Calc {
public:int Add(int a, int b) { return a + b; }
};TEST_F(MyTest, AddMock) {MOCK_METHOD(Calc, Add).stubs().will(returnValue(42));Calc calc;ASSERT_EQ(calc.Add(1, 2), 42);
}

3 对比总结

特性gmockmockcpp
Mock 方式基于虚函数接口函数地址拦截,可 Mock 普通函数
对老代码支持差,需重构为虚接口强,无需修改原代码
语法风格现代,强类型安全,表达式链式调用类似脚本语言的 DSL,易用但类型不安全
调用验证支持 EXPECT_CALL支持 .expects().with(...)
可测试对象虚函数、成员函数所有函数(包括静态函数、全局函数)
依赖关系依赖 gtest独立,兼容多种测试框架
编译兼容性高度依赖编译器特性,现代 GCC/Clang 更好支持低层 hook,有些编译器和系统下不稳定
适合应用新代码、接口良好的模块老代码、未封装接口的遗留项目

4 实际使用建议

  • 如果你在做现代 C++ 项目(C++11+)并使用 gtest 作为测试框架,推荐使用 gmock,配合 gtest 效果更佳;
  • 如果你在维护遗留项目、无法改写为虚函数接口,或者需要对 静态函数、全局函数、第三方库函数进行打桩,推荐使用 mockcpp;
  • 也可以在一个项目中同时使用 gmock 和 mockcpp,根据不同的模块情况选择合适的 Mock 方式。
http://www.xdnf.cn/news/14006.html

相关文章:

  • Server 11 ,⭐通过脚本在全新 Ubuntu 系统中安装 Nginx 环境,安装到指定目录( 脚本安装Nginx )
  • Houdini GPU 云渲染:成本与时间的精准测算
  • 《TCP/IP 详解 卷1:协议》第7章:防火墙和网络地址转换
  • PCB设计教程【大师篇】stm32开发板PCB整体布局
  • LLM之RAG实战(五十五)| 阿里开源新模型,Qwen3-Embedding与Qwen3 Reranker强势来袭!
  • curl 检查重定向的命令总结
  • “窮” 字拆解分析:从字形到文化的深度解构
  • Amazon Linux 2023 配置定时任务完全指南:cronie安装与使用
  • Day53打卡 @浙大疏锦行
  • 淘宝天猫商品数据爬取方案:官方API与非官方接口对比
  • OpenLayers 图层控制
  • 《 第三章-招式初成》 C++修炼生涯笔记(基础篇)程序流程结构
  • 网络原理10 - HTTP完
  • 【Spreadsheet】香港规范结构设计电子表格库开发方案
  • postman Access denied for user‘root‘@‘XXXXXXXX(using password: YES)
  • Flotherm许可管理工具和软件
  • 【强化学习漫谈】4. 从统一视角看 LLM Post-Training
  • 透视黄金窗口:中国有机杂粮的高质量跃迁路径
  • 瑞萨RA-T系列芯片马达类工程TCM加速化设置
  • 爬虫系统异常监控并邮件通知源码
  • 202558读书笔记|《雨季不再来(轻经典)》——日子总有停住的一天,大地要再度绚丽光彩起来
  • 【Create my OS】2 开启中断
  • 魔方在线工具箱 —— 开启便捷高效的在线工具之旅
  • yolov8自训练模型作为预训练权重【增加新类别】新增类别的数据集与旧数据集合并重新训练模型
  • pycharm读取不同格式的数据集用于神经网络模型训练
  • keil下载安装
  • PDF处理控件Aspose.PDF教程: 在 Java 中编辑 PDF 页面大小
  • Mac电脑通过 IntelliJ IDEA 远程连接 MySQL 的详细教程
  • CANoe入门(2)-- 创建一个简单的Panel来改变TX的信号值
  • (2)SpringBoot 3 + Vue 3 前后端分离项目,集成 Flowable