这篇文章我们就一起来学习mock打桩相关的内容。

在嵌入式项目开发中,我们常常会遇到这些困境:

  • 硬件还没就绪,依赖硬件的代码无法调试;
  • 第三方接口 / 驱动未完成,联调卡壳;
  • 单元测试时,无法隔离被测试模块与依赖模块的耦合

Mock 打桩技术,正是解决这些问题方案。它能模拟依赖模块的行为,让被测试代码 “脱离依赖” 独立运行,是嵌入式单元测试、模块调试的核心技术之一。

一、什么是 Mock 打桩?

1.1 核心定义

  • Mock(模拟):创建一个 “假的” 依赖模块(如硬件驱动、第三方接口、复杂算法模块),其对外接口与真实模块完全一致,但内部逻辑是简化的(仅满足被测试模块的需求)。
  • 打桩(Stub):通过技术手段,将被测试代码中对真实依赖模块的调用,“拦截并替换” 为对 Mock 模块的调用 —— 相当于在调用链路中 “打一个桩子”,让请求绕到 Mock 模块。

嵌入式 Mock 打桩的核心是函数调用重定向—— 让 CPU 执行被测试代码时,原本要跳转到真实依赖函数的指令,改为跳转到 Mock 函数。

二、什么是CMock?

CMock是一个自动化生成Mock的工具。它的核心价值在于:通过解析头文件自动生成完整的Mock实现。

https://github.com/ThrowTheSwitch/CMock

MIT license

CMock是ThrowTheSwitch工具链中的重要成员,与Unity紧密集成。

  • Unity:轻量级 C 单元测试框架,只关心断言和测试用例组织。
  • CMock:基于 Ruby 的 C 头文件解析 + Mock 代码生成器,帮你把依赖模块“伪装”成可控的假对象。

具体例子工作流如:

三、CMock + Unity 例子

被测模块:temp_controller。

需要Mock(模拟)的模块:temperature_sensor。

  1. 准备 Ruby
sudo apt update
sudo apt install -y ruby
  1. 准备CMock库
git clone https://github.com/ThrowTheSwitch/CMock
一个可自动生成嵌入式Mock模块的工具!

克隆得到:

可以看到,unity是一个CMock的子模块。执行git submodule update --init --recursive命令初始化并更新CMock仓库中的子模块到本地:

工程根目录需要创建一个最小 CMock 配置 文件cmock_config.yml

cmock_config.yml文件的作用:

需要被mock(模拟)的模块如:temperature_sensor.h

一键生成Mock:

被测模块接口如:temp_controller.h

temp_controller.c模块依赖于temperature_sensor模块,可以使用CMock工具依赖temperature_sensor头文件自动生成一个假的模块,相当于代码都开发好了,temp_controller是个可被测试的模块了。

编写基于unity单元测试框架的temp_controller的单元测试文件:test_temp_controller.c

可参考例子:一个可应用于嵌入式的轻量级单元测试框架!

如:

编译运行:

总结

对嵌入式项目而言,单元测试真正难的不是框架,而是有没有做好相关隔离。CMock + Unity 提供的是一条工程化、可落地的单元测路径:解析头文件自动生成 Mock,我们可以把时间花在设计用例和理解逻辑上。