mock简介

mock原是python的第三方库。python3以后mock模块已经整合到了unittest测试框架中,不用再单独安装。Mock这个词在英语中有模拟的意思,因此我们可以猜测出这个库的主要功能是模拟一些东西。准确的说,Mock是Python中一个用于支持单元测试的库,它的主要功能是使用mock对象替代掉指定的Python对象,以达到模拟对象的行为既然mock已经被整合到了unittest单元测试框架中,可想而知mock的目的就是为了让我们更好的进行测试

mock作用

1. 解决依赖问题:当我们测试一个接口或者功能模块的时候,如果这个接口或者功能模块依赖其他接口或其他模块,那么如果所依赖的接口或功能模块未开发完毕,那么我们就可以使用mock模拟被依赖接口,完成目标接口的测试

2. 单元测试:如果某个功能未开发完成,我们又要进行测试用例的代码编写,我们也可以先模拟这个功能进行测试

3. 模拟复杂业务的接口:实际工作中如果我们在测试一个接口功能时,如果这个接口依赖一个非常复杂的接口业务,那么我们完全可以使用mock来模拟这个复杂的业务接口,其实这个和解决接口依赖是一样的原理

4.前后端联调:如果你是一个前端页面开发,现在需要开发一个功能:根据后台返回的状态展示不同的页面,那么你就需要调用后台的接口,但是后台接口还未开发完成,是不是你就停止这部分工作呢?答案是否定的,你完全可以借助mock来模拟后台这个接口返回你想要的数据

mock安装

python 3 的mock模块已经被整合到了unittest框架中,所以你使用的时候只需要在文件开头from unittest import mock 导入即可。如果你使用的是python2 那么你需要执行pip install mock安装后再 import mock即可

mock实例

一个未开发完成的功能如何测试?

假如们现在有一个实现两个数相加的功能需要编写测试用例,但是由于开发进度缓慢,只搭两个简单的框架,并没有内部实现

import unittest

from unittest import mock

class SubClass:

def add(self,a,b):

#假设功能代码还没有实现

pass

class TestSub(unittest.TestCase):

def test_sub(self):

sub=SubClass()

sub.add = mock.Mock(return_value=10)

result = sub.add(12,23)

self.assertEqual(result,10)

if __name__ == '__main__':

unittest.main()

测试结果:

.

----------------------------------------------------------------------

Ran 1 test in 0.000s

OK

Process finished with exit code

实际上mock模拟add方法的原理是,使用相同的对象方法接收mock的对象(使用sub.add接收),那么当mock对象被调用时(sub.add())就会返回return_value参数对应的数据

我们用例编写完了,而且开发既然也把功能开发完了,既然真实的功能已经可以测试了,那么我们怎么在上面用例的基础上直接测试真实功能呢?

完整的功能如何测试?

我们把用例的代码稍做修改

import unittest

from unittest import mock

class SubClass:

def add(self,a,b):

return a+b

class TestSub(unittest.TestCase):

def test_sub(self):

sub=SubClass()

sub.add = mock.Mock(return_value=10, side_effect=sub.add)

result = sub.add(12,23)

self.assertEqual(result,35)

if __name__ == '__main__':

unittest.main()

side_effect参数

代码中我们给Mock方法添加了另一个关键字参数side_effect = sub.add, 这个参数和return_value 正好相反,当传递这个参数的时候return_value 参数就会失效,而side_effect生效。这里我给的参数值是sub.add 相当于add方法的地址,那么当调用add方法时就会真实的使用add方法,也就达到了我们测试实际的add 方法。

你也可以理解为当传递了side_effect参数且值为被测方法地址时,mock就不会起作用。side_effect接收的是一个可迭代序列,当传递多个值时,那么每次调用mock时会返回不同的值

存在依赖关系的功能如何测试?

假设有这样一个场景:我们要测试一个支付接口但是这个支付接口又依赖一个第三方支付接口,那么第三方支付接口我们暂时没有权限使用,那么我们该如何测试我们自己这个接口呢?

看下面的实例,假设第三方接口和我们自己的支付接口如下:

import requests

class PayApi:

@staticmethod

def auth(card, amount):

"""

第三方支付接口

:param card: 卡号

:param amount: 支付金额

:return:

"""

pay_url = "http://www.zhifubao.com" # 第三方支付接口地址

data = {"card": card, "amount": amount}

response = requests.post(pay_url, data=data) # 请求第三方支付接口

return response # 返回状态码

def pay(self, user_id, card, amount):

"""

我们自己的支付接口

:param user_id: 用户id

:param card: 卡号

:param amount: 支付金额

:return:

"""

# 调用第三方支付接口

response = self.auth(card, amount)

try:

if response['status_code'] == '200':

print('用户{}支付金额{}成功'.format(user_id, amount))

return '支付成功'

elif response['status_code'] == '500':

print('用户{}支付失败, 金额不变'.format(user_id))

return '支付失败'

else:

return '未知错误'

except Exception:

return "Error, 服务器异常!"

if __name__ == '__main__':

pass

很明显第三方支付接口是无法访问的,因为接口的地址是我DIY的,为了模拟实际中我们无法使用的第三方支付接口编写测试用例

import unittest

from unittest import mock

from payment.PayMent import PayApi

class TestPayApi(unittest.TestCase):

def test_success(self):

pay = PayApi()

pay.auth = mock.Mock(return_value={'status_code':'200'})

status = pay.pay('1000', '12345', '10000')

self.assertEqual(status, '支付成功')

def test_fail(self):

pay = PayApi()

pay.auth = mock.Mock(return_value={'status_code':'500'})

status = pay.pay('1000', '12345', '10000')

self.assertEqual(status, '支付失败')

def test_error(self):

pay = PayApi()

pay.auth = mock.Mock(return_value={'status_code':'300'})

status = pay.pay('1000', '12345', '10000')

self.assertEqual(status, '未知错误')

def test_exception(self):

pay = PayApi()

pay.auth = mock.Mock(return_value='200')

status = pay.pay('1000', '12345', '10000')

self.assertEqual(status, 'Error, 服务器异常!')

if __name__ == '__main__':

unittest.main()

测试输出结果:

....用户1000支付失败, 金额不变

用户1000支付金额10000成功

----------------------------------------------------------------------

Ran 4 tests in 0.001s

OK

Process finished with exit code 0

从执行结果可以看出,即使第三方支付接口无法使用,但是我们自己的支付接口仍然测试通过了。也许有人会问,第三方支付都不能用,我们的测试结果是否是有效的呢?

通常我们在测试一个模块的时候,我们是可以认为其他模块的功能是正常的,只针对目标模块进行测试是没有任何问题的,所以说测试结果也是正确的,其实上述代码还可以使用另一种方式来写

import unittest

from unittest import mock

from unittest.mock import patch

from payment.PayMent import PayApi

class TestPayApi(unittest.TestCase):

def setUp(self):

self.pay = PayApi()

@patch.object(PayApi, 'auth')

def test_success(self, mock_auth):

mock_auth.return_value = {'status_code':'200'}

status = self.pay.pay('1000', '12345', '10000')

self.assertEqual(status, '支付成功')

@patch.object(PayApi, 'auth')

def test_fail(self, mock_auth):

mock_auth.return_value={'status_code':'500'}

status = self.pay.pay('1000', '12345', '10000')

self.assertEqual(status, '支付失败')

@patch.object(PayApi, 'auth')

def test_error(self, mock_auth):

mock_auth.return_value={'status_code':'300'}

status = self.pay.pay('1000', '12345', '10000')

self.assertEqual(status, '未知错误')

@patch.object(PayApi, 'auth')

def test_exception(self, mock_auth):

mock_auth.return_value='200'

status = self.pay.pay('1000', '12345', '10000')

self.assertEqual(status, 'Error, 服务器异常!')

if __name__ == '__main__':

unittest.main()

还有mock一个普通函数,mock多个方法等,这里先不赘述,写法和上面实例差不多

最后

mock还有很多自带的功能方法且mock功能很强大,也不是一句两句话就能说完了,本篇文章主要介绍了mock的基本使用方法,甚是简单,对于实际中如何应用,如何掌握更强大的方法还需自己慢慢摸索

python模块使用教程详解_python之mock模块基本使用方法详解相关推荐

  1. python中update是啥意思_python中update的基本使用方法详解

    前言 Python 字典 update()方法用于更新字典中的键/值对,可以修改存在的键对应的值,也可以添加新的键/值对到字典中. 语法格式 d.update(e) 参数说明 将e中键-值对添加到字典 ...

  2. python什么模块动态调用链接库_Python调用C/C++动态链接库的方法详解

    本文以实例讲解了Python调用C/C++ DLL动态链接库的方法,具体示例如下: 示例一: 首先,在创建一个DLL工程(本例创建环境为VS 2005),头文件: 1 2 3 4 5 6 7 8 9 ...

  3. python计算平方用map函数_python的map函数的使用方法详解以及使用案例(处理每个元素的自增、自减、平方等)...

    1.用我们之前学过的求一下平方(只有一个列表) #求平方 num=[1,5,6,2,7,8] a=[]for n innum: a.append(n**2)print(a) C:python35pyt ...

  4. python安装pip配置安装源_Python切换pip安装源的方法详解

    一.pip简介 Pip 是安装python包的工具,提供了安装包,列出已经安装的包,升级包以及卸载包的功能. Pip 是对easy_install的取代,提供了和easy_install相同的查找包的 ...

  5. python email模块详解_Python使用email模块对邮件进行编码和解码的实例教程

    解码邮件python自带的email模块是个很有意思的东西,它可以对邮件编码解码,用来处理邮件非常好用. 处理邮件是一个很细致的工作,尤其是解码邮件,因为它的格式变化太多了,下面先看看一个邮件的源文件 ...

  6. python sys模块详解_python之sys模块详解

    sys模块功能多,我们这里介绍一些比较实用的功能,相信你会喜欢的,和我一起走进python的模块吧! sys模块的常见函数列表 sys.argv: 实现从程序外部向程序传递参数. sys.exit([ ...

  7. python argparse模块详解_python自学argparse模块

    argparse模块 argparse是python用于解析命令行参数和选项的标准模块,用于代替已经过时的optparse模块 使用步骤import argparse  # 导入模块,这个没什么说的 ...

  8. python面向对象编程的三大特性_Python面向对象总结及类与正则表达式详解

    Python3 面向对象 -------------------------------------------------------------------------------- 一丶面向对象 ...

  9. python创建双链表_Python双链表原理与实现方法详解

    本文实例讲述了Python双链表原理与实现方法.分享给大家供大家参考,具体如下: Python实现双链表 文章目录 Python实现双链表 单链表与双链表比较 双链表的实现 定义链表节点 初始化双链表 ...

  10. python标准库random中函数的作用_Python随机函数库random的使用方法详解

    Python随机函数库random的使用方法详解 前言 众所周知,python拥有丰富的内置库,还支持众多的第三方库,被称为胶水语言,随机函数库random,就是python自带的标准库,他的用法极为 ...

最新文章

  1. Java老矣,尚能饭否?2020 Java生态系统报告出炉
  2. 前端ajax封装对象数组,后台的取法
  3. LeetCode Algorithm 507. 完美数
  4. 重磅!微软发布新一代 Teams 开发工具 —— Teams Toolkit!不止VS Code extension!
  5. 作为一个上市公司HR,跟大家分享一些面试的真相
  6. C/C++程序员必须熟悉的开源库
  7. android view setleft,android – 在新textview上使用setLeft / setRight方法
  8. python没有return语句的函数将返回_为什么Python没有return返回值
  9. SQL Server高级查询之常见数据库对象(触发器)第五章节
  10. 初级维修电工实训装置
  11. 树莓派触摸屏校准以及QT触摸屏相关问题解决
  12. 【Linux系统开发】Study210开发板刷安卓系统
  13. 概念理解:财新服务业PMI
  14. 【CameraX】Android CameraX 综述
  15. E - The Journey of Geor Autumn(线性DP,前缀和)
  16. Windows 10蓝牙只能发送文件到手机而无法从手机接收文件
  17. Windows Kits(Windows 工具包)
  18. 台式计算机无线网络连接打印机,台式机怎么样连接无线打印机
  19. 哈曼卡顿连接电脑后,突然变的声音好小的解决办法
  20. 哈佛结构与冯诺依曼结构(含STM32系统结构解析)

热门文章

  1. 阿里云高级技术专家彦林:云原生架构下的微服务演进
  2. 3d游戏编程大师技巧 源代码_C/C++编程新手入门基础系列:俄罗斯方块小游戏制作源代码...
  3. 【图像处理基础】基于matlab图像Harris角点检测【含Matlab源码 1731期】
  4. 【三维路径规划】基于matlab RRT算法无人机三维路径规划【含Matlab源码 155期】
  5. 【物理应用】基于matlab GUI工程供配电系统【含Matlab源码 1051期】
  6. flutter 判断是不是调试模式_Flutter之撸一个漂亮的登录界面的总结
  7. mysql数据库存储数组_数据库索引的知识点,你所需要了解的都在这儿了
  8. mysql无法远程连接 111_如何解决远程连接mysql出现Can't connect to MySQL server on (111 Connection refused)的问题...
  9. oracle 12c transaction guard,保障业务连续性的神器
  10. python导出excel 身份证_如何使用Python导出Excel文件?