C/C++ test中文网站 > 热门推荐 > C/C++test Mock怎么用 C/C++test Mock与Stub如何取舍
教程中心分类
C/C++test Mock怎么用 C/C++test Mock与Stub如何取舍
发布时间:2026/04/24 14:57:55

  很多人第一次用C/C++test做单元测试时,会把Mock和Stub混着说,这很正常。Parasoft自家的产品页会直接写它能创建mocks、stubs和assertions,但真正落到工具里的具体做法,官方文档更多是围绕stubs、Stub Callbacks和Stub Expectations来展开。换句话说,在C/C++test里,平时说的Mock,很多时候并不是另一套完全独立的机制,而是用桩函数加回调配置、再加期望校验,把依赖替换和交互验证一起做出来。

  一、C/C++test Mock怎么用

 

  这一块真要上手,最稳的思路不是先纠结术语,而是先把工具里的桩能力开起来,再用回调和期望把“像Mock一样的行为控制”补上。官方文档明确说明,Stub Callbacks用来做测试用例级的桩逻辑,Stub Expectations用来校验调用次数这类预期,所以一套完整Mock流程,通常就是这两部分的组合。

 

  1、先把桩相关执行能力打开

 

  做Mock之前,先确认测试配置里允许使用function stubs。官方说明写得很直接,若使用桩,Instrumentation mode要设成Full、Full runtime w/o coverage,或者至少是包含stub instrumentation的自定义模式;如果是No instrumentation,函数桩不会生效。

 

  2、先到【Parasoft】里的【Show View】打开【Stubs】视图

 

  官方文档给了固定入口,Stubs视图就是收集符号、生成Auto Stub、创建User Stub的工作区。第一次打开如果还没跑过单元测试配置,界面会提示Symbols data not collected,这时先跑一轮收集符号数据,再回来建桩。

 

  3、先生成桩,再配测试用例级行为

 

  官方建议的起步动作很明确,先对目标依赖函数使用Generate Auto Stub或Create User Stub。生成以后,不急着改桩函数本体,可以直接在Test Case Editor里新增Stub Configuration步骤,为具体测试用例定义返回值、参数处理、断言或调用动作。这样做的好处是,同一个桩不用为了不同用例反复改文件。

 

  4、需要像Mock一样校验交互时,加上【Stub Expectations】

 

  如果你不只是想“替换返回值”,还想判断某个依赖是否被调用、调用了几次,那就不能只停在普通Stub。官方文档说明,Stub Expectations可以配置精确调用次数、大于、小于或区间范围,而且这一步要放在相关Call步骤之前,才能把调用计数完整地抓到。

 

  5、需要默认走真实实现时,启用回落到原函数

 

  有些场景不是完全隔离依赖,而是只想在个别用例里拦截。官方提供了现成做法,同时打开Enable Stub Callbacks和Insert call to original function。这样一来,注册了测试专用回调时就执行自定义逻辑,没注册时就回落到原函数,相当于让桩以代理模式工作。

 

  二、C/C++test Mock与Stub如何取舍

 

  这一步最怕走极端。把所有依赖都当成Mock,测试会很碎;什么都不隔离,又很容易把单元测试做成集成测试。Parasoft自己在博客里对两者的区分很清楚,Stub更偏向返回预设值,Mock更偏向行为控制和交互验证。在C/C++test的实际落地里,可以把它理解成“只替换结果时用Stub,需要验证行为时把它升级成带回调和期望的Mock式用法”。

 

  1、只想给依赖一个稳定输出时,优先选Stub

 

  如果你只是想让外部函数返回固定值、切断数据库、时钟、硬件或第三方接口带来的波动,普通Stub就够了。官方文档说明,没配置测试用例级逻辑时,自动桩会按桩定义执行,默认通常返回0、false或null这类简单值,这就很适合做基础隔离。

 

  2、同一个依赖在不同调用次序下要表现不同,选Mock式配置更合适

 

  一旦你需要第一调用返回成功、第二调用返回失败,或者想按调用序号给出不同数据,普通固定Stub就开始吃力了。官方文档在Stub Configuration里专门提供了按调用次序配置参数的方式,也支持在代码模式里用stubCallInfo的callNo做分支,这就是典型的Mock式场景。

  3、要验证调用次数、调用是否发生,选带Expectations的Mock式做法

 

  如果你的测试目的已经变成“确认某个依赖是否被调用两次”“确认异常分支下不应该调用某接口”,那重点已经不是返回值,而是交互行为。这个时候更适合上Stub Expectations,因为它天然就是为调用次数预期准备的。

 

  4、依赖真实环境难初始化、不稳定、太慢时,更倾向Mock

 

  Parasoft博客给出的判断标准很实用,真实依赖如果难初始化、会让测试不稳定、很难判断结果,或者响应太慢,就更适合用mock implementation替代。像硬件坐标输入、系统时钟、慢速外设这类对象,继续硬连真实实现,往往会让单元测试越来越像现场调试。

 

  5、想保留更多真实路径,只做局部替换时,选代理式Stub

 

  有些依赖不是完全不能用,而是大多数测试想走真实实现,只有少数用例要改行为。这个时候直接启用call original的桩会更平衡,因为默认还是原函数,只有需要的时候才注册测试专用回调,不会把整条调用链一下子全切断。

 

  三、C/C++test团队里怎样把Mock用稳

 

  真正把Mock用顺,不在于术语说得多漂亮,而在于团队有没有统一一套判断口径。Parasoft的资料里其实已经给了很实用的边界,测试工件会以源代码形式生成,便于审阅和版本控制;同时,用户桩、自动桩、原函数之间还有明确优先级。这说明团队完全可以把Mock和Stub的使用规则收成固定做法,而不是每个人各写一套。

 

  1、先从Stub起步,再往上加Expectations

 

  大多数依赖隔离问题,先用Stub就能解决。只有当你真的需要验证行为,再往上加Stub Expectations。这样测试更容易读,也更不容易为了“像Mock”而把用例写得过重。

 

  2、一条用例只验证一类交互

 

  如果一条测试里既想校验返回值、又想校验三层依赖的调用关系,还想顺手把异常恢复也看了,最后通常不好维护。更稳的做法是,一条用例只盯一个依赖行为点,其它依赖保持简单桩。这个建议是工程经验判断,但和Parasoft对单元隔离、协作者替换的整体思路是一致的。

 

  3、优先隔离时钟、硬件、网络和难初始化组件

 

  这些依赖最容易让测试变慢、变脆、变得不可重复。Parasoft博客列出来的几个判断问题,核心也都在指向这类对象,所以团队可以先把它们列成默认隔离候选,而不是每个新项目都重新争一遍。

 

  4、别忘了桩优先级会影响结果

 

  官方明确说明,C/C++test使用桩时有优先级顺序,user-defined stub在前,自动生成的safe stub其次,然后才是original function和auto stub。也就是说,只要用户桩还在,它就会继续接管调用,哪怕后面真实实现已经补齐。所以测试结束后,该清理的桩要清理,该注释的要注释。

 

  5、把生成的测试代码一并纳入版本库

 

  Parasoft产品页明确说,测试工件是以源代码形式生成的,适合审阅和版本控制。对团队来说,这一点很重要,因为Mock配置、Stub回调和Expectations一旦只留在某个人本机里,后面别人接手时几乎一定会失真。

  总结

 

  C/C++test Mock怎么用,最实用的理解方式不是另外找一套独立框架,而是先建Stub,再用Stub Callbacks和Stub Expectations把行为控制和交互校验补齐。C/C++test Mock与Stub如何取舍,判断也不复杂,固定返回值、单纯隔离依赖时先用Stub;需要按调用次序改行为、校验调用次数和交互关系时,再升级成Mock式配置。把这条线分清以后,测试既不会做得太重,也不会因为隔离不够把单元测试拖成集成测试。

135 2431 0251