温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Python中Mock如何使用

发布时间:2021-07-10 16:40:48 来源:亿速云 阅读:250 作者:Leah 栏目:编程语言

Python中Mock如何使用,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

 1. 前言

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

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

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

2. Mock 介绍

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

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

它的优势包含:

  • 前、后端并行开发

  • 模拟无法访问的资源

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

3.1 mock

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

# 安装mock依赖  pip3 install mock

假设 Product 类中有 2 个方法

  • get_product_status_by_id

  • buy_product

其中,get_product_status_by_id 方法还没有实现;buy_product 方法依赖于  get_product_status_by_id 方法的返回值

# product_impl.py  class Product(object):      def __init__(self):         pass      def get_product_status_by_id(self, product_id):         """         通过商品id获取产品信息(Mock)         :return:         """         # 待实现查询数据库的业务逻辑         pass      def 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 patch  from 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 mock  from unittest_mock.product_impl import Product  class 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") == 0  if __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 pytest  from pytest_mock_.product_impl import Product  def test_buy_product_success(mocker):     """     购买成功Mock     :param mocker:     :return:     """     # 实例化一个产品对象     product = Product()      # 对Product中的方法的返回值进行Mock     mock_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

关于Python中Mock如何使用问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注亿速云行业资讯频道了解更多相关知识。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI