需求分析

在做C语言的单元测试的时候,我们希望在不改动源码的情况下,额外加入单元测试用的代码。借用cmocka这样的测试框架,希望能够通过mock来替代源代码中的函数。例如待测函数是A,而A调用了B,那么最好是可以通过mock_B来让A直接获取到返回值,从而把A定义的流程走完。

尝试

通过搜索,找到了一个可以执行的例子如下

/* test_mocking.c */
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>int get_value();
int __wrap_get_value() {int v;v = mock_type(int);return v;
}int add_one() {int v;v = get_value();return v + 1;
}static void add_test(void **state) {(void)state;int a;will_return(__wrap_get_value, 3);a = add_one();assert_int_equal(a, 4);
}int main(int argc, char *argv[]) {const struct CMUnitTest tests[] = {cmocka_unit_test(add_test),};return cmocka_run_group_tests(tests, NULL, NULL);
}

进行编译,确实可以起到用add_one调用的是 __wrap_get_value而不是get_value的效果。

$ gcc test_mocking.c -I. -Wl,--wrap=get_value -lcmocka && ./a.out
[==========] Running 1 test(s).
[ RUN      ] add_test
[       OK ] add_test
[==========] 1 test(s) run.
[  PASSED  ] 1 test(s).

但是,注意到源码中只是声明get_value,而并没有实现get_value这个函数。如果实现这个函数再尝试编译执行

/* test_mocking.c */
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>int get_value() {return 20;
}
......$ gcc test_mocking.c -I. -Wl,--wrap=get_value -lcmocka && ./a.out
[==========] Running 1 test(s).
[ RUN      ] add_test
[  ERROR   ] --- 0x15 != 0x4
[   LINE   ] --- test_mocking.c:30: error: Failure!
[  FAILED  ] add_test
[==========] 1 test(s) run.
[  PASSED  ] 0 test(s).
[  FAILED  ] 1 test(s), listed below:
[  FAILED  ] add_test1 FAILED TEST(S)

发现wrap就无效了,add_one调用的就是get_value自身定义的实现,而不是__wrap_get_value了!

结论

在stackoverflow找到了一个跟我诉求一样的帖子,回答的人特意提到,要被wrap的函数,必须是未定义实现

    --wrap=symbolUse a wrapper function for symbol. Any undefined reference to symbol will be resolved to __wrap_symbol. Any undefined reference to __real_symbol will be resolved to symbol.

这样看来,想完全“不打扰”源码中的实现,额外加单元测试的念头,用cmocka是不行了。

涉及gcc wrap的一个问题的探索相关推荐

  1. 腾讯朱华:数据中心下一个风向的探索

    导读:朱华,腾讯数据中心技术发展中心总监,中国工程建设标准化协会数据中心技术委员会副主任委员,中国通信标准化协会开放数据中心委员会数据中心工作组组长,荣获中国工程建设标准化协会颁发的2018数据中心青 ...

  2. Windows下使用MinGw和gcc构建第一个C程序、g++构建第一个C++程序

    gcc与g++都gnu的编译器:gcc是c语言的编译器:g++是c++的编译器:gdb 是调试工具. 看着有些面生:都是Linux的东西: MinGw 是 Minimal GNU on Windows ...

  3. [Linux基础环境/软件]Linux下安装resin web服务器(涉及gcc、jdk环境部署)

    由于Ubuntu自带是没有jdk和gcc编译器的,而安装resin需要C编译器和jdk的支持,而且resin本身是java写的.另外我本身的网站是zip打包的,所以linux也要安装了gcc.jdk. ...

  4. 一个优雅地探索相关性的新可视化方法

    一个古老的诅咒一直萦绕着数据分析:我们用来改进模型的变量越多,那么我们需要的数据就会出现指数级的增长.不过,我们通过关注重要的变量就可以避免欠拟合以及降低收集大量数据的需求.减少输入变量的一种方法是鉴 ...

  5. golang游戏开发学习笔记-创建一个能自由探索的3D世界

    此文写在golang游戏开发学习笔记-用golang画一个随时间变化颜色的正方形之后,感兴趣可以先去那篇文章了解一些基础知识,在这篇文章里,我们将创建一个非常简单(只有三个方块)但能自由探索的的3D世 ...

  6. 在vmware中安装centos并使用gcc执行第一个c语言代码

    目录 1.安装虚拟机VMWare 2.下载镜像文件(这里使用的是centos7) 3.如果你之前centos不想要了,请按照下面图片进行删除 4.打开VMWare创建配置虚拟机 5.配置安装CentO ...

  7. mysql多线程使用一个链接_探索多线程使用同一个数据库connection的后果

    在项目中看到有用到数据库的连接池,心里就思考着为什么需要数据库连接池,只用一个连接会造成什么影响?(只用一个connection)? 1  猜想:jdbc的事务是基于connection的,如果多线程 ...

  8. 源码环境下跟进MO通话流程(涉及到其中每一个方法的跳转)

    对Tele这一块的MO流程在源码环境下做一个跟进,通过观察每一个方法的跳转加深对MO流程的印象,如有错误,欢迎在评论区指出,篇幅较长,请耐心阅读. packages/apps/Dialer/java/ ...

  9. gcc编译流程及中间表示层RTL的探索

    gcc编译流程及中间表示层RTL的探索收藏 新一篇: 解读VC++编程中的文件操作API和CFile类 | 旧一篇: Effective Item21 尽可能使用const 内容摘要 本文将以 C 语 ...

最新文章

  1. 记录智能指针使用shared_ptr使用错误
  2. 阿里“火拼”拼多多,要“1元”抢占下沉市场
  3. CSS大小设置实例——盒子模型
  4. 程序员的三门课之项目管理篇
  5. 输入一个以回车结束的字符串,判断该字符串是否对称(正序与逆序相同,如aBc2cBa为对称字符串)
  6. 瓦片经纬度及行列号转换_ArcGIS根据最大最小坐标换算瓦片行列号
  7. 由replaceAll引发的java.util.regex.PatternSyntaxException错误
  8. java统计空格代码_java统计文件中字符,数字,汉字,空格数目
  9. J2EE运动会管理系统(含源码)
  10. [转载]看我花式绕过校园网计费认证
  11. 输入100以内含7或7倍数的数
  12. python 实现excel单元格合并和导出
  13. pm2启动node项目
  14. 利用python计算fasta文件中ATGC的含量
  15. Oracle sql脚本中注释
  16. DDC EDID 介绍
  17. 分布式微服务企业快速架构之SpringCloud分布式、微服务、云架构快速开发平台
  18. c#导入地图(一)--地图Gmap的使用
  19. CSS浮动--慕课网
  20. 01 esp32c3 Arduino 开发环境搭建

热门文章

  1. 设置QLineEidt部件输入时自动切换到英文输入法(无法输入中文)
  2. 第三方软件检测机构的工作流程都有哪些?如何选择好的检测公司?
  3. ZIGBEE(CC2530,ZSTACK)串口波特率自适应
  4. yzm10与战地信使 yzm10原创系列
  5. 循环结构及猜数小游戏
  6. idea项目中出现0% methods, 0%lines covered
  7. R0~R16寄存器作用
  8. IntelliJ IDEA 的安装、配置和使用
  9. iOS系统H264视频硬件编解码说明
  10. DAVINCI DM365-DM368开发攻略——linux-2.6.32的移植