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

单元测试 Mock不Mock?

文章目录

  • 前言
  • 单元测试没必要?
  • Mock不Mock?
    • 什么是Mock?
    • Mock的意义何在?
  • 如何Mock?
    • 应该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,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,可以避免外部变化对测试结果的影响。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • P7072 [CSP-J2020] 直播获奖
  • 解决Metasploit调用Nessus报错问题
  • Kafka【十三】消费者消费消息的偏移量
  • 使用LLaMA-Factory快速训练自己的专用大模型
  • 在 Windows 环境下实现免密登录 Linux 服务器
  • Spring之Bean的生命周期 2024-9-6 19:47
  • 水晶连连看 - 无限版软件操作说明书
  • 分布式光伏的优势
  • 深度学习从入门到精通——yolov3算法介绍
  • K8s中pod控制器
  • vscode debug
  • MySQL数据库的介绍
  • yarn create vite时报错error Error: EPERM: operation not permitted, mkdir
  • STM32+ESP8266+MQTT协议连接阿里云实现温湿度上传
  • .NET/C#⾯试题汇总系列:⾯向对象
  • (ckeditor+ckfinder用法)Jquery,js获取ckeditor值
  • angular2 简述
  • extjs4学习之配置
  • iOS 系统授权开发
  • Redux 中间件分析
  • 高程读书笔记 第六章 面向对象程序设计
  • 关于 Cirru Editor 存储格式
  • 线上 python http server profile 实践
  • 协程
  • AI算硅基生命吗,为什么?
  • 如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes ...
  • ​软考-高级-信息系统项目管理师教程 第四版【第14章-项目沟通管理-思维导图】​
  • # 计算机视觉入门
  • ###51单片机学习(1)-----单片机烧录软件的使用,以及如何建立一个工程项目
  • #APPINVENTOR学习记录
  • #QT(TCP网络编程-服务端)
  • (delphi11最新学习资料) Object Pascal 学习笔记---第2章第五节(日期和时间)
  • (DFS + 剪枝)【洛谷P1731】 [NOI1999] 生日蛋糕
  • (Matalb分类预测)GA-BP遗传算法优化BP神经网络的多维分类预测
  • (Oracle)SQL优化基础(三):看懂执行计划顺序
  • (Redis使用系列) Springboot 实现Redis消息的订阅与分布 四
  • (八)光盘的挂载与解挂、挂载CentOS镜像、rpm安装软件详细学习笔记
  • (附源码)spring boot公选课在线选课系统 毕业设计 142011
  • (附源码)springboot优课在线教学系统 毕业设计 081251
  • (附源码)计算机毕业设计ssm高校《大学语文》课程作业在线管理系统
  • (九)信息融合方式简介
  • (三十)Flask之wtforms库【剖析源码上篇】
  • (十六)视图变换 正交投影 透视投影
  • (十一)c52学习之旅-动态数码管
  • (四)Android布局类型(线性布局LinearLayout)
  • (转) ns2/nam与nam实现相关的文件
  • (转)3D模板阴影原理
  • (转)setTimeout 和 setInterval 的区别
  • **CI中自动类加载的用法总结
  • .Net OpenCVSharp生成灰度图和二值图
  • .Net高阶异常处理第二篇~~ dump进阶之MiniDumpWriter
  • .NET国产化改造探索(一)、VMware安装银河麒麟
  • .NET轻量级ORM组件Dapper葵花宝典
  • .net通用权限框架B/S (三)--MODEL层(2)
  • .net与java建立WebService再互相调用