cmocka入门教程

文章目录

    • 摘要
    • 前言
    • 什么是mock
    • mock示例
      • cmocka安装
      • 使用mock function替换subfunction
      • 控制mock function的输入和输出

摘要

本文介绍cmocka中,mock的使用。


前言

在这之前,需要了解最基本的cmocka使用。如果之前有gtest的编程经验,掌握cmocka的简单使用非常容易。这里有份入门文档,我不再赘述:使用 cmocka 进行单元测试 | 前尘逐梦

单元测试框架的基本逻辑是:

  • 测试内容相似的,放在一个组。这个通常称为Test Fixtures(Using the Same Data Configuration for Multiple Tests)。
  • 相同数据的准备和清除动作,通常由setup/teardown这两组函数来执行。
  • 一个具体的单元测试中,通常使用断言(Assertions),来决定单元测试是否通过。
  • 然后就是mock,这个有点高级,也是本文介绍的内容。

什么是mock

cmocka 是一个优雅的 C 单元测试框架,支持mock objects。它只需要标准的 C 库,可以在一系列计算平台(包括嵌入式)和不同的编译器上工作。

什么是mock呢?我问了下chatgpt, 它告诉我这些内容:

在单元测试中,Mock是一种测试技术,用于模拟(或称为替代)系统的组件或依赖项。当编写单元测试时,我们通常希望专注于测试当前正在编写的代码单元,而不是依赖于其他组件或外部系统。为了实现这一目标,我们可以使用Mock对象来替代这些依赖项,以便我们能够控制测试环境并验证代码的行为。使用Mock的主要目的是:

  1. 模拟外部依赖项:例如,当测试一个函数,它依赖于数据库或网络服务时,我们可以使用Mock对象代替实际的数据库或网络服务,以确保测试的独立性和可控性。
  2. 简化测试环境:有时,某些依赖项可能很难配置或设置,使用Mock对象可以避免设置这些复杂的依赖项,从而简化测试环境的搭建。
  3. 控制测试场景:Mock对象可以模拟各种情况和条件,使测试更全面和灵活。

嗯,说的挺好。但如果是第一次接触mock,还是会不明白。因为上面只是告诉了我们mock的好处/必要性,但是该怎么实现呢?

我们通过图片来说明,图片来自:Unit testing and mocking wi nd mocking with cmocka

当我们想对一个函数(function)进行单元测试时,但是这个函数内部调用了子函数(subfunction)。函数的结果由子函数决定,但是子函数的返回值是变化的/依赖外部数据库等。此时,想给函数添加单元测试,殊为不易。单元测试-函数-子函数的调用链如下所示:

在这里插入图片描述

此时,如果我们能在调用函数时,使用我们自定义的函数(mock function)替换掉子函数。并且,如果我们可以控制这个mock function的输入和输出,并将mock funciton的输出喂给函数,那么我们就可以给函数添加单元测试了。mock过程如下图所示:

在这里插入图片描述


mock示例

书接上文。mock的核心有两点:(1)单元测试中,使用mock function替换subfunction。(2)单元测试中,可以控制mock function的输入和输出

talk is cheap, show me your code.

本文的示例代码来自:example/mock/uptime · master · cmocka / cmocka · GitLab


cmocka安装

首先我们需要先下载和编译上面的示例代码。

# 为了查看示例更加方便,需要下载源码编译
## 具体如何编译,查看里面的README.md和INSTALL.md
wget https://cmocka.org/files/1.1/cmocka-1.1.7.tar.xz
tar -xvf cmocka-1.1.7.tar.xz
cd cmocka-1.1.7.tar.xz
mkdir build && cd build
cmake .. -DBUILD_SHARED_LIBS=OFF
make# 包管理器方式安装 
## alamlinux8上,这个包中只包含动态库。如果需要静态链接,只好上面源码的方式集成
dnf install libcmocka-devel

使用mock function替换subfunction

这一步需要在链接(ld)的时候做。编译链接的选项中添加-Wl,--wrap=uptime。可以看到示例的CMakeLists.txt中有这样的内容:

set_property(TARGETtest_uptimePROPERTYLINK_FLAGS"${DEFAULT_LINK_FLAGS} -Wl,--wrap=uptime")

-Wl告诉 GCC 将后面的选项传递给链接器 ld。关于--wrap选项,我在gcc手册中没有找到。这个选项在man ld中。

Use 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.
Only undefined references are replaced by the linker. So, translation unit internal references to symbol are not resolved to “__wrap_symbol”.

啥意思呢?要看明白上面的意思,还得先明白啥叫translation unit。可参考:c++ faq - What is a “translation unit” in C++? - Stack Overflow

translation unit定义:是C++中编译的基本单元。它由单个源文件的内容组成,加上它直接或间接包含的任何头文件的内容,减去使用条件预处理语句忽略的那些行。

以上一节的图为例,它的意思是,当function和subfunction位于不同文件时,使用--warp选项后,function实际会去链接__wrap_subfunction

注意,function和subfunction不能在同一个translation unit,否则--warp选项无效(我踩过这个坑了)。相关内容可见:c - GCC’s linker --wrap will not wrap over static library function - Stack Overflow、 wrapper - How to wrap existing function in C - Stack Overflow

本节具体的代码示例,可见上面的链接。(这里有篇博客,也有示例代码,但是它的代码结构不好: GCC中通过–wrap选项使用包装函数-CSDN博客)


控制mock function的输入和输出

为了说明方便,我拷贝下示例代码,完整的代码见链接example/mock/uptime · master · cmocka / cmocka · GitLab。

由于链接选项中,设置了-Wl,--wrap=uptime。所以当calc_uptime()中调用uptime()时,将会调用__wrap_uptime()。链接过程帮我们做了函数替换。此时需要使用CMocka API - Mock Objects控制__wrap_uptime()的输入输出了。

will_return(): Store a value to be returned by mock() later。

test_calc_uptime_minutes调用了两个will_return(),给__wrap_uptime放入了两个值。__wrap_uptime通过两次mock_type取出。(内部的原理不清楚,但是使用还是蛮简单的嘛。)

int __wrap_uptime(const char *uptime_path,double *uptime_secs,double *idle_secs)
{double up;double idle;/* Verify the passed value of the argument is correct */check_expected_ptr(uptime_path);/* Assign the return values */up = mock_type(double);idle = mock_type(double);if (uptime_secs != NULL) {*uptime_secs = up;}if (idle_secs != NULL) {*idle_secs = idle;}return (int)up;
}static void test_calc_uptime_minutes(void **state)
{char *uptime_str = NULL;UNUSED(state);/* Make sure the passed 'in' argument is correct */expect_string(__wrap_uptime, uptime_path, "/proc/uptime");/* We tell the uptime function what values it should return */will_return(__wrap_uptime, 508.16);will_return(__wrap_uptime, 72.23);/* We call the function like we would do it normally */uptime_str = calc_uptime();/* Now lets check if the result is what we expect it to be */assert_non_null(uptime_str);assert_string_equal(uptime_str, "up 8 minutes");free(uptime_str);
}

这里,我再顺道介绍下expect_stringcheck_expected_ptr。这两个函数在cmocka API - Checking Parameters中。

test_calc_uptime_minutes“大吼一声”,我要在calc_uptime调用__wrap_uptime时,检查下uptime_path这个变量是不是"/proc/uptime"。test_calc_uptime_minutes在执行前设置了期望;__wrap_uptime在执行时,验证期望。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/805545.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Node2Vec论文翻译

node2vec: Scalable Feature Learning for Networks node2vec:可扩展的网络特征学习 ABSTRACT 网络中节点和边缘的预测任务需要在学习算法使用的工程特征上付出仔细的努力。最近在更广泛的表示学习领域的研究通过学习特征本身在自动化预测方面取得了重大进展。然…

我认识的建站公司老板都躺平了,每年维护费都大几十万。

这些老板们过的悠哉游哉,大富大贵没有,达到中产,活得舒服,没毛病。 企业官网每年需要交维护费主要是因为以下几个原因: 网站服务器和域名费用:企业官网需要通过服务器进行托管和访问,同时需要…

第一个Swift程序

要创建第一个Swift项目,请按照以下步骤操作: 打开Xcode。如果您没有安装Xcode,可以在App Store中下载并安装它。在Xcode的欢迎界面上,选择“Create a new Xcode project”(创建新Xcode项目)。在模板选择界面上,选择“App”(应用程序)。在应用模板选择界面上,选择“Si…

基于SSM+Jsp+Mysql的农产品供销服务系统

开发语言:Java框架:ssm技术:JSPJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包…

蓝桥杯第十二届c++大学B组详解

目录 1.空间 2.直线 3.路径 4.卡片 5.货物摆放 6.时间显示 7.砝码称重 8.杨辉三角 9.双向排序 10.括号序列 1.空间 题目解析:1Byte 8bit 1kb 1024B 1MB 1024kb; 先将256MB变成Byte 256 * 1024 * 1024; 再将32位 变成Byte就是 32 / 8 4;…

三种常见webshell工具的流量特征分析

又来跟师傅们分享小技巧了,这次简单介绍一下三种常见的webshell流量分析,希望能对参加HW蓝队的师傅们有所帮助。 什么是webshell webshell就是以asp、php、jsp或者cgi等网页文件形式存在的一种代码执行环境,主要用于网站管理、服务器管理、…

第十二届蓝桥杯省赛真题(C/C++大学B组)

目录 #A 空间 #B 卡片 #C 直线 #D 货物摆放 #E 路径 #F 时间显示 #G 砝码称重 #H 杨辉三角形 #I 双向排序 #J 括号序列 #A 空间 #include <bits/stdc.h> using namespace std;int main() {cout<<256 * 1024 * 1024 / 4<<endl;return 0; } #B 卡片…

【spring】@Profile注解学习

Profile介绍 在Spring框架中&#xff0c;Profile注解用于根据特定的配置文件来有条件地激活或禁用Bean的定义。这在开发和测试过程中非常有用&#xff0c;因为它允许你为不同的环境&#xff08;如开发、测试、生产&#xff09;定义不同的配置。 Profile不仅可以标注在方法上&…

【MATLAB源码-第184期】基于matlab的FNN预测人民币美元汇率 输出预测图误差图RMSE R2 MAE MBE等指标

操作环境&#xff1a; MATLAB 2022a 1、算法描述 前馈神经网络&#xff08;Feedforward Neural Network, FNN&#xff09;是最简单也是应用最广泛的人工神经网络之一。在许多领域&#xff0c;尤其是数据预测方面&#xff0c;FNN已经展现出了卓越的性能和强大的适应性。 一、…

【论文速读】| MASTERKEY:大语言模型聊天机器人的自动化越狱

本次分享论文为&#xff1a;MASTERKEY: Automated Jailbreaking of Large Language Model Chatbots 基本信息 原文作者&#xff1a;Gelei Deng, Yi Liu, Yuekang Li, Kailong Wang, Ying Zhang, Zefeng Li, Haoyu Wang, Tianwei Zhang, Yang Liu 作者单位&#xff1a;南洋理工…

13 指针(上)

指针是 C 语言最重要的概念之一&#xff0c;也是最难理解的概念之一。 指针是C语言的精髓&#xff0c;要想掌握C语言就需要深入地了解指针。 指针类型在考研中用得最多的地方&#xff0c;就是和结构体结合起来构造结点(如链表的结点、二叉树的结点等)。 本章专题脉络 1、指针…

ht1622不显示无反应问题解决

如果你正在写ht1622 驱动时&#xff0c;怎么看程序都没问题&#xff0c;抓取波形&#xff0c;示波器分析波形&#xff0c;如果都没有问题&#xff0c;那么很大可能是硬件问题&#xff0c;检测看看 ht1622 RD是不是接地了。 RD 低会进入读取模式&#xff0c;所以不用RD 请将RD悬…

Harmony鸿蒙南向驱动开发-RTC

RTC&#xff08;real-time clock&#xff09;为操作系统中的实时时钟设备&#xff0c;为操作系统提供精准的实时时间和定时报警功能。当设备下电后&#xff0c;通过外置电池供电&#xff0c;RTC继续记录操作系统时间&#xff1b;设备上电后&#xff0c;RTC提供实时时钟给操作系…

Python:如何对FY3D TSHS的数据集进行重投影并输出为TIFF文件以及批量镶嵌插值?

完整代码见 Github&#xff1a;https://github.com/ChaoQiezi/read_fy3d_tshs&#xff0c;由于代码中注释较为详细&#xff0c;因此博客中部分操作一笔带过。 01 FY3D的HDF转TIFF 1.1 数据集说明 FY3D TSHS数据集是二级产品(TSHS即MWTS/MWHS 融合大气温湿度廓线/稳定度指数/…

第十一届蓝桥杯省赛真题(C/C++大学B组)

试题A &#xff1a;门牌制作 #include <bits/stdc.h> using namespace std;const int N 100000; int arr[N];int main() {int ans 0,t;for(int i 1;i < 2020;i){t i;while(t > 0){if(t % 10 2) ans;t / 10;}}cout<<ans<<endl;return 0; } 试题B …

Harmony鸿蒙南向驱动开发-MMC

MMC&#xff08;MultiMedia Card&#xff09;即多媒体卡&#xff0c;是一种用于固态非易失性存储的小体积大容量的快闪存储卡。 MMC后续泛指一个接口协定&#xff08;一种卡式&#xff09;&#xff0c;能符合这种接口的内存器都可称作MMC储存体。主要包括几个部分&#xff1a;…

[lesson17]对象的构造(上)

对象的构造(上) 对象的初始化 从程序设计的角度&#xff0c;对象只是变量&#xff0c;因此&#xff1a; 在栈上常见对象时&#xff0c;成员变量初始为随机值在堆上创建对象时&#xff0c;成员变量初始为随机值在静态存储区创建对象时&#xff0c;成员变量初始为0值 生活中的对…

[Java基础揉碎]Arrays类

目录 Arrays常见方法 1) toString返回数组的字符串形式 Arrays.toString(arr) 2) sort 排序(自然排序和定制排序) Integer arr[] {1,-1,7,0,89}; 定制排序 查看源码 冒泡排序 3) binarySearch 通过二分搜索法进行查找下标&#xff0c;要求必须排好序 int index Arra…

【MATLAB源码-第29期】基于matlab的MIMO,MISO,SIMO,SISO瑞利rayleigh信道容量对比。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 1. SISO&#xff08;单输入单输出&#xff09;&#xff1a; - SISO 是指在通信系统中&#xff0c;只有一个天线用于传输信号&#xff0c;也只有一个天线用于接收信号的情况。这是最简单的通信方式。 2. SIMO&#xff08;单…

2024年河北省职业院校技能大赛高职组“信息安全管理与评估”赛项样题

培训、环境、资料、考证 公众号&#xff1a;Geek极安云科 网络安全群&#xff1a;775454947 网络系统管理群&#xff1a;223627079 网络建设与运维群&#xff1a;870959784 极安云科专注于技能提升&#xff0c;赋能 2024年广东省高校的技能提升&#xff0c;受赋能的客户院校均…