1. 前言

微服务架构下,由于各类服务开发进度的不一致,导致联调工作经常会存在不确定性,进而导致项目延期

在实际工作中,为了保证项目进度,我们经常需要针对部分未完成模块及不稳定模块采用 Mock 方式,以验证已开发完的模块

本篇文章将介绍 Python 实现 Mock 的几种常见方式

2. Mock 介绍

Mock 测试:在测试验证过程中,对于那些尚未完成或不稳定的对象,用一个虚拟对象来替代,以便测试的测试方法

因此,这个虚拟的对象是 Mock 对象,Mock 对象是真实对象在调试期间的代替品

它的优势包含:

  • 前、后端并行开发

  • 模拟无法访问的资源

  • 隔离系统,避免脏数据干扰测试结果

3.1 mock

在 Python 3.3 之前使用 mock,需要先安装依赖

# 安装mock依赖
pip3 install mock

项目地址:

https://github.com/testing-cabal/mock

假设 Product 类中有 2 个方法

  • get_product_status_by_id

  • buy_product

其中,get_product_status_by_id 方法还没有实现;buy_product 方法依赖于 get_product_status_by_id 方法的返回值
# product_impl.pyclass Product(object):def __init__(self):passdef get_product_status_by_id(self, product_id):"""通过商品id获取产品信息(Mock):return:"""# 待实现查询数据库的业务逻辑passdef buy_product(self, product_id):"""购买产品(真实逻辑):return:"""# 产品信息# {"id":1,"name":"苹果","num":23}product = self.get_product_status_by_id(product_id)if product.get("num") >= 1:result = {"status": 0, "msg": "购买成功!"}else:result = {"status": 1, "msg": "购买失败,库存不足!"}return result
Mock 的步骤如下:
  • 导入使用 mock 中的 patch 方法

  • 作为测试方法的装饰器,对 get_product_status_by_id 方法进行 Mock,方法参数为 Mock 对象

  • 测试方法中,对该 Mock 对象设置一个返回值

  • 调用并断言

from mock import patch
from mock_.product_impl import Product@patch('mock_.product_impl.Product.get_product_status_by_id')
def test_succuse(mock_get_product_status_by_id):# Mock方法,指定一个返回值mock_get_product_status_by_id.return_value = {"id": 1, "name": "苹果", "num": 23}product = Product()assert product.buy_product(1).get("status") == 0

需要注意的是,Mock 此方法的时候,必须制定该方法的完整路径

使用 @patch.object 同样能完成 Mock,不同的是,@patch.object 包含 2 个参数

第一个参数为该方法所在的类;第二个参数为方法名

from mock import patchfrom mock_.product_impl import Product# Mock一个方法
# @patch.object:对象、方法名
@patch.object(Product, 'get_product_status_by_id')
def test_succuse(mock_get_product_status_by_id):# Mock方法,指定一个返回值mock_get_product_status_by_id.return_value = {"id": 1, "name": "苹果", "num": 23}product = Product()assert product.buy_product(1).get("status") == 0

3.2 unittest.mock

Python 3.3 之后,mock 作为标准库,已经内置到 unittest 中了

还是以 3.1 的场景为例,使用 unittest 编写一个测试用例

Mock 步骤如下:

  • 导入 unittest 框架中的 mock 文件

  • 实例化 Product 对象

  • mock.Mock(return_value=*) 方法

    对 get_product_status_by_id 方法进行 Mock

  • 调用并断言

import unittest
from unittest import mockfrom unittest_mock.product_impl import Productclass TestProduct(unittest.TestCase):def test_success(self):# 成功结果mock_success_value = {"id": 1, "name": "苹果", "num": 23}product = Product()product.get_product_status_by_id = mock.Mock(return_value=mock_success_value)# 调用实际函数assert product.buy_product(1).get("status") == 0if __name__ == "__main__":unittest.main()

3.3 pytest.mock

相比 unittest,pytest 由于强大的插件支持,用户群体可能更大!

如果项目本身使用的框架是 pytest,则 Mock 更建议使用 pytest-mock 这个插件

# pytest依赖
pip3 install pytest

Mock 步骤如下:

  • 使用 pytest 编写测试方法,参数为 mocker

  • 实例化 Product 对象

  • 使用 mocker.patch() 方法对 get_product_status_by_id 方法进行 Mock,并设置返回值

  • 调用并断言

import pytestfrom pytest_mock_.product_impl import Productdef test_buy_product_success(mocker):"""购买成功Mock:param mocker::return:"""# 实例化一个产品对象product = Product()# 对Product中的方法的返回值进行Mockmock_value = {"id": 1, "name": "苹果", "num": 23}# Mock方法# 注意:需要指定方法的完整路径# mocker.patch 的第一个参数必须是模拟对象的具体路径,第二个参数用来指定返回值product.get_product_status_by_id = mocker.patch("product_impl.Product.get_product_status_by_id",return_value=mock_value)# 调用购买产品的方法result = product.buy_product(1)assert result.get("status") == 0

需要注意的是,mocker.patch 方法第一个参数必须是 Mock 对象的完整路径

4. 最后

文中对 Python 中常见的 Mock 方案进行了讲解,实际应用中,建议根据项目实际情况进行选型。

推荐阅读

误执行了rm -fr /*之后,除了跑路还能怎么办?!

程序员必备58个网站汇总

大幅提高生产力:你需要了解的十大Jupyter Lab插件

----------  END  ----------

Python 中 Mock 到底该怎么玩?一篇文章告诉你(超全)相关推荐

  1. 线上python课程一般多少钱-python培训班一般多少钱?一篇文章告诉你

    如今,职场竞争越来越激烈.如果不学习一两项新技能并不断更新你的知识,很容易被年轻一代超越.很多人开始学习python.那么,python培训班一般多少钱? Python语法简洁,代码十分接近人类的自然 ...

  2. 【一篇文章告诉你网格策略从理论到实盘的所有内容(python实现)】

    一篇文章告诉你网格策略从理论到实盘的所有内容 名词定义 什么是网格策略 现货网格的基本参数 等差网格以及等比网格 什么是网格的价格中枢以及目标仓位 无常损失的与业绩计算 需要"市价补仓&qu ...

  3. 一篇文章告诉你如何成为数据科学家

    文章讲的是一篇文章告诉你如何成为数据科学家,通常来说,年轻人都很容易立志成为什么,例如成为一名科学家,然后又很快放弃.这一方面是因为摆在他们面前的诱惑太多,也因为成为一名科学家真的很不容易. 这一点放 ...

  4. 《看聊天记录都学不会C语言?太菜了吧》(7)下一篇文章告诉你牛郎是谁

    若是大一学子或者是真心想学习刚入门的小伙伴可以私聊我,若你是真心学习可以送你书籍,指导你学习,给予你目标方向的学习路线,无套路,博客为证. 本系列文章将会以通俗易懂的对话方式进行教学,对话中将涵盖了新 ...

  5. 【ArcGIS风暴】什么是点云?什么是Las数据集?一篇文章告诉你点云数据的奥秘

    摄影测量Pix4d等软件,或激光雷达数据一般都是LAS格式的点云数据,有很大的适用范围和优点,那么,到底什么是LAS数据集呢,一文告诉你LAS数据集的来龙去脉. 扩展阅读: 什么是点云?什么是Las数 ...

  6. 运营商大数据怎么获客的?一篇文章告诉你

                     运营商大数据怎么获客的?一篇文章告诉你 现在各种各样的广告营销越来越难即便精准如百度竞价,好多访客也只是看看就走开了,浪费了大量的推广费用,想知道客户的联系方式好做二 ...

  7. lcl手术和飞秒区别_一篇文章告诉你,ICL与全飞秒近视手术的区别在哪?

    原标题:一篇文章告诉你,ICL与全飞秒近视手术的区别在哪? >>近视眼的痛,你体会过么? 戴眼镜给外表减分.隐形眼镜护理麻烦 升学.参军.找工作受限 还要时刻警惕 随时存在的视网膜脱离.青 ...

  8. 一篇文章告诉你标准化和归一化的区别?

    一篇文章告诉你标准化和归一化的区别? 2019-02-28 17:12:39 融融网融融网阅读量:484 进一步推进企业的标准化工作,使之发展水平适应经济全球化下市场竞争的要求,促进企业综合实力的提升 ...

  9. python中cgi到底是什么_十分钟搞懂什么是CGI(转)

    原文:CGI Made Really Easy,在翻译的过程中,我增加了一些我在学习过程中找到的更合适的资料,和自己的一些理解.不能算是严格的翻译文章,应该算是我的看这篇文章的过程的随笔吧. CGI真 ...

最新文章

  1. 远程办公时,有哪些提高沟通效率的技巧?
  2. 本科发表6篇SCI论文,获多个荣誉,他刚入学就享受研究生待遇!
  3. 【译】Engineering Security Through Coordination Problems
  4. Oracle 11g 安装后续——开发工具篇
  5. 记录webpack使用问题,使用报错“UnhandledPromiseRejectionWarning,file-loader图片过大,无法加载图片,打包html文件报错TypeError
  6. python中提取几列_Python一键提取PDF中的表格到Excel(实例50)
  7. 不用掉一根头发!用 Flutter + Dart 快速构建一款绝美移动 App
  8. 网易“吃鸡”,干腾讯何事?
  9. Android 帧动画 (一)
  10. MyCat 主键ID自增长配置
  11. java写企业员工信息管理系统
  12. 使用WireShark抓包对方QQ的ip地址(通过QQ电话)
  13. SOLIDWORKS批量转化PDF图纸的方法
  14. TTL转RS232电路
  15. GoCN社区Go读书会第二期:《Go语言精进之路》直播文字稿
  16. Spring session redis ERR unknown command 'CONFIG'
  17. 吃内存狂魔?微信官方工具来了:深度清理缓存
  18. 自动化测试 selenium 模块 webdriver使用02
  19. 高可用架构的6大常规方案【转】
  20. 安装Visual Studio Scrum 1.0过程模板

热门文章

  1. 解决Tomcat运行springboot打包war工程,出现: Unable to compile class for JSP 的问题
  2. 用python操作mysql数据库(之批量插入数据)
  3. PHP 单元测试工具 SimpleTest
  4. PHP验证码相关函数
  5. jQuery中的for循环var与let区别
  6. c++ protected_合理使用protected关键字,确保类属性的安全性
  7. html text 默认选中,html - 如何在Shiny中默认选择verbatimTextOutput中的文本? - SO中文参考 - www.soinside.com...
  8. linux下的定时任务处理
  9. php页面代码简化,代码求简化
  10. python遍历目录树_在Python中遍历目录树的速度要快得多?