场景实验室获得IDG资本数千万元A+轮融资,吴声对未来新物种做出10个预测
06-18
前言 前段时间,我们团队就单元测试是否使用Mock进行了讨论,大家都有自己的看法。这篇文章给出了我对单元测试 Mock 与否的看法。
欢迎各位同仁提出不同意见,互相讨论、交流。单元测试没必要吗?我见过很多不写单元测试的项目。
给出的理由大多是:“没有必要”、“浪费时间”、“无法获得单体测试的作用”。此类项目要么是小型项目,要么是大铁项目。
我之前也有同样的观点...单元测试在软件开发过程中还是非常重要的。除了提高代码质量之外,引入CI/CD后的自动化测试流程可以起到快速部署和交付的作用。
每次上线都需要“一点一点”测试吗?我想凡是有过这种经历的人都深有体会。模拟还是不模拟?那么什么是模拟呢?什么是模拟?简单来说,Mock是在实际测试过程中模拟目标代码的行为并替换真实的调用目标。
这样做有什么意义,如下图所示? Mock 的意义是什么?试想一下,如果单元测试时出现以下问题该怎么办?单元测试产生的涉及DB操作、网络调用等的数据算垃圾数据吗?会影响生意吗?生产环境发布/部署过程中,单元测试执行错误导致生产问题怎么办?如果CI流程中的测试阶段时间太长怎么办?会影响整合交付吗?我想大多数开发者都经历过上述问题,那么如何避免这些问题呢?我认为 Mock 是最好的方法。如果将涉及到的外部操作,比如DB操作、网络调用等行为进行mock,就不会出现垃圾数据的问题,也不用担心环境切换带来的问题。
还可以模拟外部耗时操作来避免 CI。过程太长了。
个人认为Mock只是模拟调用外部设备的行为,并不影响代码逻辑。因此,不存在“Mock是否是有效的单元测试”这样的问题。
怎么嘲讽?什么应该被嘲笑?通常,我们编写的方法(或函数)是由很多方法分层组成的。就像这样,当我们对顶层方法进行单元测试时,哪些方法应该被mock?如果Mock方法1、2、3,那么方法4、5、6就不会被调用,里面的逻辑也不会被覆盖,也就是说它不是一个有效的单元测试。
如果修改Mock方法4、5、6的逻辑或者返回值,那么就必须递归向上修改,这是不符合软件工程的。但是,如果方法43、5、6都涉及DB或网络调用等外部不可控操作,我们应该Mock它们。
因此,一些稳定且不可控的方法应该被嘲笑。Mock编写示例以Python中的Mock框架为例。
示例如下: 代码语言:python 代码运行次数:0 复制 Cloud Studio 代码运行 class TestXxService(unittest.TestCase): def test_init(self): XXService.update(xx )class XXService: def update(xx): ....test_init函数中的update会涉及到数据库操作。这里,patch 用于模拟这两个函数的行为。
代码语言:python 代码运行次数:0 复制Cloud Studio代码运行 #patch("目标函数路径")patch('....update') 模拟的情况下,XXService.update会被模拟的函数替换执行代码语言:python 代码运行次数:0 复制Cloud Studio代码运行 def test_init(self): with patch('....update') as mocked_update: # 调用业务逻辑函数 XXService.update(xx)在模拟上下文中,mocked_update.assert_used_once_with(xx),其中,assert_used_once_with将验证模拟函数是否被调用过一次,并将验证预期接收的参数是否匹配。如果没有参数,则使用assert_used_once来验证是否被调用过一次。
如果模拟的函数实际上被调用了多次,则需要按照以下方式进行编码: python code run times: 0 Copy Cloud Studio code run # 断言mocked_update被调用了2次 self.assertEqual(mocked_update.call_count, 2) # 断言调用mocked_update,参数正确mocked_update.assert_any_call(xx) 如果函数有返回值,定义mock函数时,添加return_value,return_value可以是任意类型。代码语言:python 代码运行次数:0 复制 Cloud Studio 代码在验证返回值时按照以下方式运行 patch('...update', return_value='xxx') as mocked_update 代码语言:python 代码运行次数:0 复制Cloud Studio代码运行 xxxx = mocked_update.return_valueself.assertEqual(xxxx, 'xxx') 通过示例,我们模拟了XXService.update行为,实现了XXService的隔离测试,保证了测试的可靠性和高效性。
总结一下,在单元测试中使用 Mock 有以下好处: 隔离测试:Mock 可以让测试专注于测试的代码逻辑,而不必担心外部的不稳定因素。提高测试速度:模拟可以通过避免耗时的外部调用来加快测试速度。
提高测试的可靠性和稳定性:Mock可以避免外部变化对测试结果的影响。
版权声明:本文内容由互联网用户自发贡献,本站不拥有所有权,不承担相关法律责任。如果发现本站有涉嫌抄袭的内容,欢迎发送邮件 举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。
标签:
相关文章
06-17
06-06
06-17
最新文章
【玩转GPU】ControlNet初学者生存指南
【实战】获取小程序中用户的城市信息(附源码)
包雪雪简单介绍Vue.js:开学
Go进阶:使用Gin框架简单实现服务端渲染
线程池介绍及实际案例分享
JMeter 注释 18 - JMeter 常用配置组件介绍
基于Sentry的大数据权限解决方案
【云+社区年度征文集】GPE监控介绍及使用