深入了解模拟和存根:提高单元测试质量的关键技术

一、引言

在进行单元测试时,我们经常会遇到对外部资源的依赖,如数据库、网络接口等。模拟(Mocking)和存根(Stubbing)是两种帮助我们模拟这些外部资源,使我们能够在隔离环境中测试单元的方法。在本文中,我们将详细介绍模拟和存根,以及如何在单元测试中使用它们。

二、模拟和存根是什么?

模拟和存根都是用来模拟外部资源的技术,但它们的关注点略有不同:

  1. 存根(Stubs):存根是用来提供预设行为的。它们在你调用方法时返回一个特定的值或抛出一个异常。

  2. 模拟(Mocks):模拟不仅提供预设行为,还能检查调用的次数、参数等。通常我们用模拟来验证一个对象是否正确地使用了另一个对象。

三、使用模拟和存根的例子

下面,我们将使用JavaScript中的流行测试库,Jest,来展示如何使用模拟和存根。

例1:使用存根

假设你有一个函数getUserName,它从数据库中获取用户的名字。你想要测试这个函数,但是不想依赖真实的数据库。

  1. async function getUserName(userId) {

  2. const user = await db.getUser(userId);

  3. return user.name;

  4. }

你可以使用Jest的jest.fn()方法来创建一个存根:

  1. const db = {

  2. getUser: jest.fn()

  3. };

  4. db.getUser.mockResolvedValue({ name: 'Alice' });

  5. expect(await getUserName(1)).toBe('Alice');

在这个例子中,我们创建了一个存根来代替db.getUser方法。这个存根总是返回一个具有名字"Alice"的用户。

例2:使用模拟

假设你有一个login函数,它调用了一个authentication服务来验证用户的凭据。你想要测试这个函数,但是你更关心它是否正确地调用了authentication服务。

  1. async function login(username, password) {

  2. return await authentication.authenticate(username, password);

  3. }

你可以使用Jest的jest.fn()方法来创建一个模拟:

  1. const authentication = {

  2. authenticate: jest.fn()

  3. };

  4. authentication.authenticate.mockResolvedValue(true);

  5. await login('Alice', 'password');

  6. expect(authentication.authenticate).toHaveBeenCalledWith('Alice', 'password');

在这个例子中,我们创建了一个模拟来代替authentication.authenticate方法。然后,我们使用toHaveBeenCalledWith方法来验证login函数是否正确地调用了authentication.authenticate方法。

四、结论

模拟和存根是单元测试中的重要工具。它们帮助我们创建隔离的测试环境,使我们能够集中测试代码的特定部分,而不必担心其他外部依赖项。

下面是一些更深入使用模拟和存根的示例:

例3:更复杂的存根行为

在有些情况下,你可能想要模拟一些更复杂的行为,例如抛出异常。你可以通过配置存根来实现这一点。

  1. const db = {

  2. getUser: jest.fn()

  3. };

  4. db.getUser.mockRejectedValue(new Error('User not found'));

  5. try {

  6. await getUserName(1);

  7. } catch (e) {

  8. expect(e.message).toBe('User not found');

  9. }

在这个例子中,我们配置存根在被调用时抛出一个错误。然后,我们在测试中捕获这个错误,并验证它的消息是否正确。

例4:模拟函数调用的次数

除了验证模拟函数是否被正确的参数调用,你还可以验证模拟函数被调用的次数。

  1. const authentication = {

  2. authenticate: jest.fn()

  3. };

  4. authentication.authenticate.mockResolvedValue(true);

  5. await login('Alice', 'password');

  6. await login('Bob', 'password');

  7. expect(authentication.authenticate).toHaveBeenCalledTimes(2);

在这个例子中,我们使用toHaveBeenCalledTimes方法来验证login函数是否调用了两次authentication.authenticate方法。

五、结语

模拟和存根是一种强大的工具,可以帮助你编写出更加健壮和可维护的单元测试。通过了解何时以及如何使用这些工具,你可以更有效地测试你的代码,而无需担心外部依赖的复杂性。希望以上的示例可以帮助你在实践中更好地理解和应用模拟和存根。

六、参考链接

  • Jest: https://jestjs.io/

  • Sinon (另一款支持存根和模拟的JavaScript测试库): http://sinonjs.org/

行动吧,在路上总比一直观望的要好,未来的你肯定会感 谢现在拼搏的自己!如果想学习提升找不到资料,没人答疑解惑时,请及时加入扣群: 320231853,里面有各种软件测试+开发资料和技术可以一起交流学习哦。

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!

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

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

相关文章

分布式任务调度框架xxl-job使用手册

官网地址和文档地址:https://www.xuxueli.com/xxl-job/ 一、快速入门 1.1 下载源码 https://github.com/xuxueli/xxl-job https://gitee.com/xuxueli0323/xxl-job 下载完成后有以下模块 1.2 初始化数据库 官方指定mysql8.0,但我是mysql5.7 执行/xxl…

PyQt6--Python桌面开发(6.QLineEdit单行文本框)

QLineEdit单行文本框 import sys import time from PyQt6.QtGui import QValidator,QIntValidator from PyQt6.QtWidgets import QApplication,QLabel,QLineEdit from PyQt6 import uicif __name__ __main__:appQApplication(sys.argv)uiuic.loadUi("./QLine单行文本框.u…

Qt 6.7功能介绍

Qt 6.7为我们所有喜欢在构建现代应用程序和用户体验时获得乐趣的人提供了许多大大小小的改进。一些新增内容作为技术预览发布,接下来我们就一起来看看吧: 将C20与Qt一起使用 对于许多编译器工具链来说,C20仍然是可选的和实验性的,…

台服dnf局域网搭建,学习用笔记

台服dnf局域网搭建 前置条件虚拟机初始化上传安装脚本以及其他文件至虚拟机密钥publickey.pem客户端配置如果IP地址填写有误,批量修改IP地址 前置条件 安装有vmvarecentos7.6镜像:https://mirrors.tuna.tsinghua.edu.cn/centos-vault/7.6.1810/isos/x86…

Python注意事项【自我维护版】

各位大佬好 ,这里是阿川的博客 , 祝您变得更强 个人主页:在线OJ的阿川 大佬的支持和鼓励,将是我成长路上最大的动力 阿川水平有限,如有错误,欢迎大佬指正 本篇博客在之前的博客上进行的维护 创建Python…

Day7 字符串和常用数据结构

文章目录 字符串和常用数据结构使用字符串使用列表生成式和生成器使用元组使用集合使用字典练习练习1:在屏幕上显示跑马灯文字。练习2:设计一个函数产生指定长度的验证码,验证码由大小写字母和数字构成。练习3:设计一个函数返回给…

linux下使用jexus部署aspnet站点

1.运行环境 Centos 7 安装dos2unix工具 yum install dos2unix 安装jexus curl https://jexus.org/release/x64/install.sh|sudo sh2.网站部署 2.1. 将windows下的网站发布包Msc_qingdao_admin.zip上传到linux中, 然后解压后放入/var/www(没有则创建)目录下 r…

福昕PDF阅读器取消手型工具鼠标点击翻页

前言: 本文介绍如何关闭福昕PDF阅读器取消手型工具鼠标点击翻页,因为这样真的很容易误触发PDF翻页,使用起来让人窝火。 引用: NA 正文: 新版的福昕PDF阅读器默认打开了“使用手型工具阅读文章”这个勾选项&#x…

超全MySQL锁机制介绍

前言 MySQL作为关系型数据库管理系统中的佼佼者,为了保证数据的一致性和完整性,在并发控制方面采用了锁机制。锁机制是数据库管理系统用于控制对共享资源的访问,避免多个事务同时修改同一数据造成的数据不一致问题。了解MySQL的锁机制对于数…

中信证券:量子产业蓄势待发,看好相关投资机会!

在1994年,数学家彼得肖尔(Peter Shor)首次提出了现在广为人知的肖尔算法,那时许多人认为量子计算机的概念遥不可及、纯属幻想。然而,到了2024年,全球正深入探讨量子科技在现实世界的应用,以及所…

pytorch技术栈

张量(Tensors):PyTorch的核心数据结构,用于存储和操作多维数组。 自动微分(Autograd):PyTorch的自动微分引擎,可以自动计算梯度,这对于训练神经网络至关重要。 数据加载…

Git 如何管理标签命令(tag)

1.查看本地仓库tag --1.查看本地仓库tag UserDESKTOP-2NRT2ST MINGW64 /e/GITROOT/STARiBOSS/STARiBOSS-5GCA (gw_frontend_master) $ git tag 1stBossUpgrade V10.0.1_20220224_test V10.0.1_20220301_test tag-gwfrontend-V1.0.12-230625 tag-gw_frontend-23.08.29 tag-gw_f…

45.乐理基础-音符的组合方式-复附点

复附点: 复附点顾名思义就是两个附点 复附点表示的音符,有多少拍?下面拿 复附点四分音符举例,可以把整个音符看成三部分,第一部分是原本的四分音符,第二部分是第一个附点,第三部分是第二个附点&…

vue cmd执行报错 ‘vue‘ 不是内部或外部命令

使用vue脚手架快速搭建项目,在cmd中执行:vue init webpack vue-demo,报错: vue 不是内部或外部命令,也不是可运行的程序 或批处理文件。 解决方法,执行如下的命令 npm config list 注意:找到prefix等号后…

python之并发编程

python之并发编程 线程的创建方式线程的创建方式(方法包装)线程的创建方式(类包装)join()【让主线程等待子线程结束】守护线程【主线程结束,子线程就结束】 锁多线程操作同一个对象(未使用线程同步)多线程操作同一个对象(增加互斥锁,使用线程同步)死锁案…

ChatGLM 本地部署指南(问题解决)

硬件要求(模型推理): INT4 : RTX3090*1,显存24GB,内存32GB,系统盘200GB 如果你没有 GPU 硬件的话,也可以在 CPU 上进行推理,但是推理速度会更慢。 模型微调硬件要求更高。…

【双碳系列】碳中和、碳排放、温室气体、弹手指、碳储量、碳循环及leap、cge、dice、openLCA模型

气候变化是当前人类生存和发展所面临的共同挑战,受到世界各国人民和政府的高度关注 ①“双碳”目标下资源环境中的可计算一般均衡(CGE)模型实践技术应用 可计算一般均衡模型(CGE模型)由于其能够模拟宏观经济系统运行…

在论文写作中使用 LaTeX 生成算法伪代码

最近在论文写作中,我需要表示算法的逻辑。由于 Word 没有较好的模板,因此我选择使用 LaTeX 来生成算法伪代码,然后将其截图或转换为 SVG 格式,贴入论文中。 关于 LaTeX 的伪代码写作技巧,可以参考这篇文章&#xff1a…

OpenBayes 一周速览|Apple 开源大模型 OpenELM 上线;字节发布 COCONut 首个全景图像分割数据集,入选 CVPR2024

公共资源速递 This Weekly Snapshots ! 5 个数据集: * COCONut 大规模图像分割数据集 * THUCNews 新闻数据集 * DuConv 对话数据集 * 安徽电信知道问答数据集 * Sentiment Analysis 中文情感分析数据集 2 个模型: * OpenELM-3B-Inst…

前端组件库图片上传时候做自定义裁剪操作

不论是vue还是react项目,我们在使用antd组件库做上传图片的时候,有一个上传图片裁剪的功能,但是这个功能默认是只支持1:1的裁剪操作,如何做到自定义的裁剪操作?比如显示宽高比?是否可以缩放和旋转操作&…