当前位置: 首页 > news >正文

单元测试 Mock不Mock?

前段时间,我们团队就单元测试是否采用 Mock 进行了一番交流,各有各的说法。本文就单元测试 Mock不Mock 给出我的观点,欢迎各位同仁提出不同的意见,共同探讨、相互交流。

单元测试没必要?

我见过好多不写单元测试的项目,大多给出的原因都是:“没必要”、“浪费时间”、“get 不到单测的作用”,这样的项目要么是小规模,要么就是头铁。

本人之前也有相同的观点...

单元测试在软件开发过程中还是非常重要的,除了可以提高代码的质量,在引入CI/CD 后的自动化测试环节可以起到快速部署、交付作用。难道每次上线都需要“点点点”测试?这一点,我想经历过的人都深有体会。

Mock不Mock?

那什么是Mock?

什么是Mock?

简单来说,Mock就是模拟目标代码的行为,在实际测试过程中代替真实的调用目标。如下图

这样做的意义何在?

Mock的意义何在?

试想一下,单元测试中如果出现以下几个问题应该怎么办?

  1. 涉及到的DB操作、网络调用等单元测试产生的数据属不属于垃圾数据?会不会影响业务?
  2. 发布/部署生产环境的过程中,错误地执行了单元测试引起生产问题怎么办?
  3. CI过程中的测试环节花费时间太长怎么办?会不会影响集成交付?

以上几个问题我想大部分开发人员都经历过,那如何避免这些问题?我想Mock就是最好的一种方式。

如果将涉及到的外部操作,例如DB操作、网络调用等行为进行Mock,那就不会存在垃圾数据的问题,也不用担心环境切换带来的问题,外部耗时的操作也可以通过Mock避免CI过程过长。

个人认为Mock只是模拟调用外部的行为,并不影响代码逻辑。所以,不存在“Mock是不是有效的单元测试”这种说法。

如何Mock?

应该Mock什么?

通常,我们编写的方法(或函数)都是由很多方法按照层级组成的,就像这样

当我们对顶层方法进行单元测试时,应该Mock哪些方法?

  • 如果Mock方法1、2、3,那么方法4、5、6就不会被调用到,里面的逻辑不会被覆盖到,也就不是有效的单元测试。
  • 如果Mock方法4、5、6,里面的逻辑或返回值有修改,那么就要递归向上修改,不符合软件工程。

但是,如果方法43、、5、6都涉及到DB或者网络调用等外部不可控操作,我们就应该对其Mock。

所以,应该Mock一些稳定的、不可控的方法。

Mock 编写示例

以Python中的Mock框架为例,下面是一个示例:

class TestXxService(unittest.TestCase): def test_init(self): XXService.update(xx) class XXService: def update(xx): ......

test_init函数中的....update会涉及到数据库的操作,这里使用patch模拟这两个函数的行为

# patch("目标函数路径") patch('....update')

在模拟的上下文中,XXService.update将会被模拟的函数替代执行

def test_init(self): with patch('....update') as mocked_update: # 在模拟的上下文中调用业务逻辑函数 XXService.update(xx) mocked_update.assert_called_once_with(xx)

其中,assert_called_once_with会验证模拟函数是否被调用了一次,并且会验证预期接收的参数是否匹配。

如果没有参数,使用assert_called_once进行验证是否被调用了一次。

如果模拟的函数实际被调用了多次,需要通过以下方式

# 断言mocked_update被调用了2次 self.assertEqual(mocked_update.call_count, 2) # 断言mocked_update被调用了,并且参数正确 mocked_update.assert_any_call(xx)

如果函数有返回值,在定义模拟函数时,添加return_value,可以是任意类型。

patch('...update', return_value='xxx') as mocked_update

在验证返回值时通过下面的方式

xxxx = mocked_update.return_value self.assertEqual(xxxx, 'xxx')

通过示例,我们Mock了XXService.update行为,实现了对XXService的隔离测试,并确保了测试的可靠性和高效性。

总结

单元测试中使用Mock有以下几个好处:

  1. 隔离测试:Mock 使得测试可以专注于测试的代码逻辑,而不必关心外部不稳定因素。
  2. 提高测试速度:Mock 可以避免耗时的外部调用,从而加快测试速度。
  3. 提高测试的可靠性和稳定性:通过Mock,可以避免外部变化对测试结果的影响。

最后:下方这份完整的软件测试 视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】

​​​件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

http://www.cnnetsun.cn/news/1954713.html

相关文章:

  • 【限时解密】2026奇点大会未公开闭门报告:AI编程助手在金融级代码审计、合规注释生成、跨语言重构三大高危场景的真实失效案例(仅剩97份内部摘要)
  • 【生成式编程安全生死线】:从GitHub Copilot到CodeWhisperer,必须启用的4层静态+动态校验机制
  • 别再手动轮询了!用DMA+ADC1多通道采集传感器数据,解放你的STM32/APM32主循环
  • 如何编写Controller的测试代码?
  • 《RocketMQ实战与进阶》 04 消息发送常见错误与解决方案
  • 苏州2026年,探秘苏州灌装机工厂的智造新篇章
  • 富集分析结果太杂乱?3个ggplot2技巧让你的气泡图秒变高颜值SCI配图
  • 构建智能能源管理系统的7个关键技术突破:OpenEMS实战指南
  • 1Panel+Docker私有仓库实战:解决镜像拉取慢/失败问题(含WordPress案例)
  • 用周立功CAN分析仪抓包解析电动汽车充电握手报文(BMS/充电机通信实战)
  • YzmCMS 5.3.0 ‘采集节点’功能竟是SSRF后门?一次对功能滥用的深度安全审计
  • BetterNCM-Installer:一键解锁网易云音乐PC版的终极插件管理器
  • Python自动化操作Creo的5个实用技巧(附代码示例)
  • GSV9001E@ACP# 参数规格 + 产品特色总结分享
  • 从.mat到.txt:手把手教你用Matlab load函数搞定各种格式的数据导入
  • 企业如何用SaaS平台实现数字化转型?3步搭建高效管理体系的实战指南
  • 别再只把Logstash当日志收集器了!手把手教你用它搞定MySQL到Elasticsearch的数据同步
  • STM32学习——.map文件知识的学习
  • 宝塔面板SSH提示连接被拒绝_检查服务器端口开关
  • 别再只盯着评分了!用BPR算法处理隐式反馈数据,让你的推荐系统更懂用户
  • 幻境·流金入门必看:DiffSynth-Studio+玄金美学环境搭建详解
  • Python函数实战:从基础分段到高级参数处理
  • 揭秘煤炉Mercari防封号终极指南
  • 从扫地机器人到无人机:用Python模拟Bug1/Bug2算法,看经典避障如何影响现代机器人
  • 【FPGA】Vivado综合进程异常终止(PID Not Specified)排查与修复指南
  • 亮数据 Bright Data 第二季度直播倒计时!
  • 别再只改单元格了!PyQt5 QTableWidget表头(horizontalHeader/verticalHeader)的5个实用技巧与避坑指南
  • 别再让虚拟机卡顿了!保姆级详解VMware ESXi内存回收三剑客:TPS、Ballooning与Swapping
  • 新概念英语(第三册)精读与场景应用——Lesson 6 至 Lesson 10 核心主题解析
  • 请在vscode中使用opencode