测试开发工程必备技能之一:Mock的使用
1. 背景
在实际产品开发过程中,某个服务或前端依赖一个服务接口,该接口可能依赖多个底层服务或模块,或第三方接口,比如说服务 A 依赖服务B,服务B又依赖服务 C
这种依赖的问题会导致原本的需求目的是要验证服务A,但由于所依赖的服务B或者服务C不稳定或者未开发完成,导致工作无法正常开展。
那作为测试工程师,面对这样的情形,我们该怎么办呢?解决这类问题的核心的思路:引入依赖服务替身,更通俗的叫法,引入Mock服务。
今天就结合unittest框架,给大家分享一些关于Mock的一些常见使用。
2. Mock是什么
可能还有些读者之前并没有接触过Mock,不清楚Mock是个啥。
Mock简单来理解,就是在测试过程中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试。而这个虚拟的对象就是mock对象。mock对象就是真实对象在调试期间的代替品。
有时也将Mock服务称之为测试服务替身,或者测试服务档板。
3. Mock能做什么
就Mock功能而言,本身适用场景较多,但在实际项目中,引入Mock常用来解决的几类,概括起来,主要有:
接口间的相互依赖
单元测试
第三方接口调用
1.前后端联调
比如你是一个前端页面开发,现在需要开发一个功能:
下一个订单,支付页面的接口,根据支付结果,支付成功,展示支付成功页,支付失败,展示支付失败页。要完成此功能,你需要调用后端的接口,根据返回给你的结果,来展示不同的页面。此时后端接口还没开发好,作为一个前端开发总不能等别人开发好了,你再开发,那你只有加班的命了。为了同步开发完成任务,此时,你可以根据接口文档的规定,把接口的地址和入参传过去,然后自己mock接口的不同返回界面,来完成前端的开发任务。
2.单元测试
由于单元测试仅针对当前单元进行测试,这就要求所有的内部或者外部依赖都应该是稳定的,采用mock的方法模拟跟本单元依赖的其他单元,可以将测试重点放在当前单元功能,排除外界因素干扰,提升测试精准度。
3.第三方接口依赖
在做接口自动化的时候,有时候需要调用第三方的接口,但是别人公司的接口服务不受你的控制,有可能别人提供的测试环境今天服务给你开着,别人就关掉了,给自动化接口测试带来很多的麻烦,此时就可以通过mock来模拟接口的返回数据,比如模拟各种第三方异常时的返回。
4. Mock实现方式
Mock虽然是作为依赖服务的替身,但并不需要原原本本去构造实现一个完整的服务逻辑,比如现在有一个A服务依赖B服务,需要通过Mock来替换B服务(做一个假的B服务替身)。
那么我们做一个 Mock 服务其实就是做了一个简单的服务 B,它不需要实现原有服务 B 负载的处理逻辑,只要能按服务A需要服务B返回的处理逻辑给出对应返回数据就可以了。
目前常见服务或接口协议主要两种,一种是RPC,另一种是HTTP/HTTPS,mock原理都类似,要么是修改原服务地址为Mock服务地址,要么是拦截原服务的请求Mock返回值,总之就是构造一个假的服务,替代原有服务。
5. Mock市面上常见的解决方案
如果你不想自己动手构建一套Mock解决方案,市面上也提供了很多现存的Mock方案。
常用的有:EasyMock、Mockito 、WireMock、JMockit、Mock、Moco。
如果你团队技术基础相对比较薄弱,推荐你看看Moco这个方案,官网如下:
https://github.com/dreamhead/moco/
接下来,重点介绍Python系下Mock方案的使用。
6. Python下unittest.mock使用
unittest.mock是一个用于在Python中进行单元测试的库,顾名思义这个库的主要功能是模拟一些东西。它的主要功能是使用mock对象替代掉指定的Python对象,以达到模拟对象的行为。
需要注意的是在Python2.x版本中,Mock需要单独安装
pip install -U mock
从Python 3.3以后的版本mock已经合并到unittest模块中了,是unittest单元测试的一部分,直接导入过来就行
from unittest import mock
官方文档:
https://docs.python.org/dev/library/unittest.mock.html
unittest.mock模块中最常用的是Mock类。
Mock类库是一个专门用于在unittest过程中制作(伪造)和修改(篡改)测试对象的类库,避免这些对象在单元测试过程中依赖外部资源(网络资源,数据库连接,其它服务以及耗时过长等)
案例:
如下场景:支付是一个独立的接口,由其它开发提供,根据支付的接口返回状态去显示失败,还是成功,这个是你需要实现的功能,代码存放在pay.py脚本中:
# !/usr/bin/python3
# -*- coding: utf-8 -*-
# @Author : Mike Zhou
# @Email : 公众号:咖啡加剁椒
# @File : pay.pydef zhifu():'''假设这里是一个支付的功能,未开发完支付成功返回:{"result": "success", "msg":"支付成功"}支付失败返回:{"result": "fail", "msg":"余额不足"}'''passdef zhifu_statues():'''根据支付的结果success or fail,判断跳转到对应页面'''result = zhifu()try:if result["result"] == "success":return "支付成功"elif result["result"] == "fail":return "支付失败"else:return "未知错误异常"except:return "Error, 服务端返回异常!"
在zhifu_statues方法中,依赖了zhifu方法,但由于zhifu支付方法的接口是由另外一个同事开发,正常情况下,你同事开发的进度你是无法控制的,需要等他开发完了你才能进行联调你所负责的zhifu_statues接口,因此我们可以通过引入Mock来解决这个问题。
引入mock后单元测试用例代码
# !/usr/bin/python3
# -*- coding: utf-8 -*-
# @Author : Mike Zhou
# @Email : 公众号:咖啡加剁椒import unittest
from unittest import mock
import payclass TestZhifuStatues(unittest.TestCase):'''单元测试用例'''def test_01(self):'''测试支付成功场景'''# mock一个支付成功的数据pay.zhifu = mock.Mock(return_value={"result": "success", "msg":"支付成功"})# 根据支付结果测试页面跳转statues = pay.zhifu_statues()print(statues)self.assertEqual(statues, "支付成功")def test_02(self):'''测试支付失败场景'''# mock一个支付失败的数据pay.zhifu = mock.Mock(return_value={"result": "fail", "msg": "余额不足"})# 根据支付结果测试页面跳转statues = pay.zhifu_statues()print(statues)self.assertEqual(statues, "支付失败")if __name__ == "__main__":unittest.main()
上述代码引入Mock后,我们就可以顺利完成对支付成功和支付异常两类场景的验证工作。(实际你可以补充更多)
mock中还有另一种实现方式,通过patch装饰器的使用,patch作为函数装饰器,为您创建模拟并将其传递到装饰函数。
用mock.patch实现如下:
# !/usr/bin/python3
# -*- coding: utf-8 -*-
# @Author : Mike Zhou
# @Email : 公众号:咖啡加剁椒import unittest
from unittest import mock
import payclass TestZhifuStatues(unittest.TestCase):'''单元测试用例'''@mock.patch("pay.zhifu")def test_001(self, mock_zhifu):'''测试支付成功场景'''# 方法一:mock一个支付成功的数据# pay.zhifu = mock.Mock(return_value={"result": "success", "msg":"支付成功"})# print(pay.zhifu())# 方法二:mock.path装饰器模拟返回结果mock_zhifu.return_value = {"result": "success", "msg":"支付成功"}# # 根据支付结果测试页面跳转statues = pay.zhifu_statues()print(statues)self.assertEqual(statues, "支付成功")@mock.patch("pay.zhifu")def test_002(self, mock_zhifu):'''测试支付失败场景'''# mock一个支付失败的数据mock_zhifu.return_value = {"result": "fail", "msg": "余额不足"}# 根据支付结果测试页面跳转statues = pay.zhifu_statues()self.assertEqual(statues, "支付失败")if __name__ == "__main__":unittest.main()
还有更多的使用技巧,篇符有限,今天就先分享到这,如果觉得有用,欢迎关注!
最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:
软件测试面试小程序
被百万人刷爆的软件测试题库!!!谁用谁知道!!!全网最全面试刷题小程序,手机就可以刷题,地铁上公交上,卷起来!
涵盖以下这些面试题板块:
1、软件测试基础理论 ,2、web,app,接口功能测试 ,3、网络 ,4、数据库 ,5、linux
6、web,app,接口自动化 ,7、性能测试 ,8、编程基础,9、hr面试题 ,10、开放性测试题,11、安全测试,12、计算机基础

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!
相关文章:
测试开发工程必备技能之一:Mock的使用
1. 背景 在实际产品开发过程中,某个服务或前端依赖一个服务接口,该接口可能依赖多个底层服务或模块,或第三方接口,比如说服务 A 依赖服务B,服务B又依赖服务 C 这种依赖的问题会导致原本的需求目的是要验证服务A&…...
Qbytearray:从十六进制字符串转字节一些注意事项
1、从十六进制字符串转字节后,按字节使用时 QByteArray data QByteArray::fromHex("cc94");printf("%x %x\n",data.at(0),data.at(0)&0xff);//若超过127,会不一样printf("%d %d\n",data.at(0),data.at(0)&0xff);…...
【Docker】Docker的使用案例以及未来发展、Docker Hub 服务、环境安全的详细讲解
前言 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。 📕作者简介:热…...
Redis有哪几种内存淘汰策略?
推荐阅读 AI文本 OCR识别最佳实践 AI Gamma一键生成PPT工具直达链接 玩转cloud Studio 在线编码神器 玩转 GPU AI绘画、AI讲话、翻译,GPU点亮AI想象空间 资源分享 「java、python面试题」来自UC网盘app分享,打开手机app,额外获得1T空间 https://dr…...
操作系统练习:在Linux上创建进程,及查看进程状态
说明 进程在执行过程中可以创建多个新的进程。创建进程称为“父进程”,新的进程称为“子进程”。每个新的进程可以再创建其他进程,从而形成进程树。 每个进程都有一个唯一的进程标识符(process identifier,pid)。在L…...
Java虚拟机(JVM):垃圾收集算法
目录 一、分代收集理论 二、标记-清除算法 三、标记-复制算法 四、标记-整理算法 一、分代收集理论 分代收集理论建立在两个分代假说之上: 1、弱分代假说:绝大多数对象都是朝生夕灭的。 2、强分代假说:熬过越多次垃圾收集过程的对象就…...
【爬虫】Requests库的使用
这个库比我们上次说的 urllib 可是要牛逼一丢丢的。通过它我们可以用更少的代码,模拟浏览器操作。 不多说,直接上手代码。 requests 常见用法 mport requests# get请求网站 r requests.get(https://www.baidu.com/) # 获取服务器响应文本内容 r.text …...
了解生成对抗网络 (GAN)
一、介绍 Yann LeCun将其描述为“过去10年来机器学习中最有趣的想法”。当然,来自深度学习领域如此杰出的研究人员的赞美总是对我们谈论的主题的一个很好的广告!事实上,生成对抗网络(简称GAN)自2014年由Ian J. Goodfel…...
opencv-人脸关键点定位
#导入工具包 from collections import OrderedDict import numpy as np import argparse import dlib import cv2#https://ibug.doc.ic.ac.uk/resources/facial-point-annotations/ #http://dlib.net/files/# 参数 ap argparse.ArgumentParser() ap.add_argument("-p&quo…...
言语理解与表达 郭熙(一)
40题 35min 逻辑填空 (20题) 题型:实词填空;成语填空;混搭填空 解题思路 词义辨析:词义侧重;固定搭配;程度较重;感情色彩 语境分析: 关联关系ÿ…...
【stable-diffusion使用扩展+插件和模型资源(上】
文章目录 前言一、插件推荐1.qrcode-monster2.sd-webui-openpose-editor3.sd-webui-depth-lib4.roop(换脸插件)5.sd-webui-qrcode-toolkit(艺术二维码)5.光源控制6.二次元转真人7.动态视频转场(loopback-waveÿ…...
面试之快速学习STL-无序关联式容器
和关联式容器一样,无序容器也使用键值对(pair 类型)的方式存储数据。不过,本教程将二者分开进行讲解,因为它们有本质上的不同: 关联式容器的底层实现采用的树存储结构,更确切的说是红黑树结构&a…...
C++线程库
C线程库是C11新增的重要的技术之一,接下来来简单学习一下吧! thread类常用接口 函数名功能thread()构造一个线程对象,没有关联任何线程函数,即没有启动任何线程。thread(fn, args1, args2, ...)构造一个线程对象,并…...
一文看懂群晖 NAS 安装 Mysql 远程访问连接
文章目录 1. 安装Mysql2. 安装phpMyAdmin3. 修改User 表4. 本地测试连接5. 安装cpolar6. 配置公网访问地址7. 固定连接公网地址 群晖安装MySQL具有高效、安全、可靠、灵活等优势,可以为用户提供一个优秀的数据管理和分析环境。同时具有良好的硬件性能和稳定性&#…...
永久设置pip指定国内镜像源(windows内)
1.首先列出国内四个镜像源网站: 一、清华源 https://pypi.tuna.tsinghua.edu.cn/simple/ 二、阿里源 https://mirrors.aliyun.com/pypi/simple 三、中科大源 https://pypi.mirrors.ustc.edu.cn/simple/ 四、豆瓣源 http://pypi.douban.com/simple/ 2.一般下载所需要…...
【SA8295P 源码分析】27 - QNX Ethernet MAC 驱动 之 emac_tx_thread_handler 数据发送线程 源码分析
【SA8295P 源码分析】27 - QNX Ethernet MAC 驱动 之 emac_tx_thread_handler 数据发送线程 源码分析 系列文章汇总见:《【SA8295P 源码分析】00 - 系列文章链接汇总》 本文链接:《【SA8295P 源码分析】27 - QNX Ethernet MAC 驱动 之 emac_tx_thread_handler() 数据发送线程…...
爬虫抓取数据时显示超时,是代理IP质量不行?
很多人在做数据抓取的时候,会遇到显示超时了,然后就没有响应了。这是什么原因的?有的人回答是使用的代理IP质量不行,这种答案,对也不对。 数据抓取时,出现超时的原因时多方面影响的,主要分为目标…...
【管理运筹学】第 5 章 | 整数规划 (2,割平面法及 0-1 变量的特性)
文章目录 引言三、割平面法四、0-1 型整数规划4.1 0-1 变量的特性4.1.1 投资问题4.1.2 约束条件满足个数问题 写在最后 引言 前文我们介绍了整数规划的一种求解方法——分支定界法,可以求解纯整数和混合整数规划问题。现在我们来学习另一种整数规划求解方法——割平…...
Vscode详细安装教程
Vscode官网下载 官网地址:Download Visual Studio Code - Mac, Linux, Windows 通过链接可以直接跳转到下面的页面当中,支持的版本有Windows、Linux、Mac,可以选择适配自己电脑的版本,一般来说应该是Windows x64的。不要直接点W…...
法线矩阵推导
法线矩阵推导 https://zhuanlan.zhihu.com/p/72734738 https://juejin.cn/post/7113952418613690382 https://blog.csdn.net/wangjianxin97?typeblog 1、为什么需要法线矩阵 vec3 normalEyeSpace modelViewMatrix * normal;如果模型矩阵执行了非等比缩放, 顶点的改变会导致法…...
JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)
LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 题目描述解题思路Java代码 题目描述 题目链接:LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...
Python实现简单音频数据压缩与解压算法
Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中,压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言,提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...
【UE5 C++】通过文件对话框获取选择文件的路径
目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 ,这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器,右键点击 .uproject 文件,选择 "Generate Visual Studio project files",重…...
快速排序算法改进:随机快排-荷兰国旗划分详解
随机快速排序-荷兰国旗划分算法详解 一、基础知识回顾1.1 快速排序简介1.2 荷兰国旗问题 二、随机快排 - 荷兰国旗划分原理2.1 随机化枢轴选择2.2 荷兰国旗划分过程2.3 结合随机快排与荷兰国旗划分 三、代码实现3.1 Python实现3.2 Java实现3.3 C实现 四、性能分析4.1 时间复杂度…...
数据结构第5章:树和二叉树完全指南(自整理详细图文笔记)
名人说:莫道桑榆晚,为霞尚满天。——刘禹锡(刘梦得,诗豪) 原创笔记:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 上一篇:《数据结构第4章 数组和广义表》…...

