【涨薪技术】深入接口测试之Mock技术

news2025/1/16 13:45:23

01、为什么要用Mock

服务端与客户端约定了接口,但服务端还没有完成开发时,客户端一般由如下处理方式:

1、在程序中写模拟数据

  • 程序中增加垃圾代码,后期还要删除,可能对代码造成影响
  • 模拟异步请求不方便
  • 服务端接口开发完成后,需要重新书写网络请求部分的代码
  • JS、iOS、Android 多前端需要分别模拟数据,重复工作量

2、使用 Nginx、http-server 等 WebServer

  • 只支持 GET 请求
  • 无法针对请求进行校验或特定处理

3、自己写简单的程序模拟返回数据

  • 开发期间 API 还处于频繁变动时期,持续调整成本较高

以上方法均不方便做单元测试对于需要演示的场景,没有后端业务服务器支撑,无法演示,客户端改造成本高所以要引入Mock技术

02、Mock使用场景

在使用Mock的过程中,发现Mock是有一些通用性的,对于一些应用场景,是非常适合使用Mock的:

1)真实对象具有不可确定的行为(产生不可预测的结果,如股票的行情)

2)真实对象很难被创建(比如具体的web容器)

3)真实对象的某些行为很难触发(比如网络错误)

4)真实情况令程序的运行速度很慢

5)真实对象有用户界面

6)测试需要询问真实对象它是如何被调用的(比如测试可能需要验证某个回调函数是否被调用了)

7)真实对象实际上并不存在(当需要和其他开发小组,或者新的硬件系统打交道的时候,这是一个普遍的问题)当然,也有一些不得不Mock的场景:

8)一些比较难构造的Object:这类Object通常有很多依赖,在单元试中构造出这样类通常花费的成本太大;

9)执行操作的时间较长Object:有一些Object的操作费时,而被测对象依赖于这一个操作的执行结果,例如大文件写操作,数据的更新等等,出于测试的需求,通常将这类操作进行Mock;

10)异常逻辑:一些异常的逻辑往往在正常测试中是很难触发的,通过Mock可以人为的控制触发异常逻辑;

11)在一些压力测试的场景下,也不得不使用Mock,例如在分布式系统测试中,通常需要测试一些单点(如namenode,jobtracker)在压力场景下的工作是否正常。而通常测试集群在正常逻辑下无法提供足够的压力(主要原因是受限于机器数量),这时候就需要应用Mock去满足;

12)在mock点的选择过程中,以下的一些点会是一些不错的选择 网络交互:如果两个被测模块之间是通过网络进行交互的,那么对于网络交互进行Mock通常是比较合适的,如RPC;

13)外部资源:比如文件系统、数据源,如果被测对象对此类外部资源依赖性非常强,而其行为的不可预测性很可能导致测试的随机失败,此类的外部资源也适合进行Mock;

14)UI:因为UI很多时候都是用户行为触发事件,系统本身只是对这些触发事件进行相应,对这类UI做Mock,往往能够实现很好的收益,很多基于关键字驱动的框架都是基于UI进行Mock;

15)第三方API:当接口属于使用者,通过Mock该接口来确定测试使用者与接口的交互。当然如何做Mock一定是与被系统的特性精密关联的,一些强制性的约束和规范是不合适的。

现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:110685036【暗号:csdn999】

03、Mock工具的选择

Mock测试工具分为单元测试级别的Mock工具和接口测试级别的Mock工具。

一、单元测试级别的Mock工具

目前,这个级别的Mock工具有easymock、jMock、Mockito、Unitils Mock、PowerMock、JMockit等等。

就目前来讲,是mockit+PowerMock、JMockit这两种工具使用人数较多。JMockit的功能最为完善,mockit+PowerMock的用户体验相对较好一点。

二、接口测试级别的Mock工具

接口级别的Mock工具完成的主要功能是对一个用户的请求,模拟server返回一个接口的响应数据。

目前,这类的主流mock工具主要有以下几种

1)Wiremock

特点:
- 支持Http响应头,匹配URL,head和body内容模式
- 请求验证
- 可以作为一个独立的进程或者WAR app在单元测试中运行
- 可以通过Java API,Json文件和JSON over HTTP配置
- 有记录/回放功能
- Fault injection
- 可以作为请求检查和替换的浏览器代理
- 有状态的行为模拟
- 可配置响应延迟

2)Mockserver

特点:
- 能够mock HTTP或者HTTPS 的server或者服务
- 当一个请求匹配 expectation时能够返回一个mock response
- 当一个请求匹配 expectation时能够forward 一个请求
- 当一个请求匹配 expectation时能够执行一个回调
(callback),允许动态地创建response
- 支持Request验证

3)Moco

4)Mock.js

5)RAP

这些了解即可;

04、搭建Mock平台

这里使用wiremock环境搭建Mock平台,具体方法如下:

WireMock 的独立安装版本其实就是一个Jar包,可以从Maven仓库中下载或者也可以在Java Maven项目中通过 pom.xml的依赖添加:

<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock-jre8-
standalone</artifactId>
<version>2.26.3</version>
<scope>test</scope>
</dependency>

除了Standalone 版本, 也可以直接在 Java代码中引用,对应Maven依赖:

<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock-jre8</artifactId>
<version>2.26.3</version>
<scope>test</scope>
</dependency>

WireMock 命令行用法

WireMock 的独立版本是一个 Jar 包,所以运行 Wiremock 自然是需要 Java 基础环境,命令如下:

java -jar wiremock-standalone-2.26.3.jar

命令行支持的一些主要参数及其作用说明如下:

  • --port 设置 Mock 服务的 http 端口,默认启动在 8080 端口
  • 如果设置为0,则自动确定端口
  • --https-port 设置 https 的端口
  • --verbose 在终端显示详细的日志信息
  • --root-dir 设置 mappings 和 __files 目录的工作路径
  • --enable-browser-proxying 以浏览器代理的方式运行

单来说,WireMoc 会在本地启动一个侦听指定端口的web服务,这里指定的端口可以用 --port 指定http协议 或 --httpsport指定https协议端口。启动后我们发到指定端口的请求,就会由WireMock来完成响应,达到接口Mock的目的,命令行启动后如图:

启动后,我们在本地运行目录下会看到 WireMock会自动生成__files 和 mappings两个目录。这两个目录中存放的就是Mock模拟的接口匹配内容了。

  • __files 存放接口响应中会用到的一些文件资源
  • mappings 存放接口响应匹配规则

具体的匹配方法我们后面再介绍,这里先介绍下WireMock本身自带的Admin接口。

Wiremock Admin 接口

WireMock 本身支持管理接口,启动后根据启动的端口,访问http://localhost:8080/__admin/docs/ ,可以看到如下两个链接:

OpenAPI 3.0 spec
Swagger UI

可以用 Swagger UI接口定义格式查看支持的管理接口

http://localhost:8080/__admin/swagger-ui/

05WireMock基本用法

1)在mappings下创建一个*.json文件

{
"request": {
"method": "GET",
"url": "/api/mocktest"
},
"response": {
"status": 200,
"bodyFileName": "response.json",
"headers": {
"Content-Type": "application/json",
"Cache-Control": "max-age=86400"
}
}
}

bodyFileName还可以是html、xml等类型的文档。

2)在__files下创建响应文件

上例中response.json 就是需要我们在__files里面建立的响应文件。其内容为:

{
"test":"wiremock"
}

在浏览器或者使用curl命令,调用

http://localhost:8080/api/mocktest ,就能返回test.json的内容了。

当然,你也可以不用创建这个文件,直接在request中将

bodyFileName改成直接body写出这个json也可以:

{
"request": {
"method": "GET",
"url": "/api/mocktest"
},
"response": {
"status": 200,
"body": "{\"test\":\"wiremock\"}",
"headers": {
"Content-Type": "application/json",
"Cache-Control": "max-age=86400"
}
}
}

06Wiremock支持的HTTP方法

1)POST

http://localhost:8080/api/products
{"request": {
"method": "POST",
"url": "/api/products",
"bodyPatterns": [{
"equalToJson": "{ \"name\": \"new
product\", \"creator\": \"tester\", \"createTime\":
\"2015-09-07\" }",
"ignoreArrayOrder" : true,
"ignoreExtraElements" : true
}]
},
"response": {
"status": 201,
"body": "Add successfully.",
"headers": {
"x-token":
"xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
}
}

bodyPatterns 请求正文的匹配模式,包括equalToJson 匹配JSON数据, ignoreArrayOrder 是否区分JSON数组元素顺序,ignoreExtraElements 是否忽略额外的元素

2)PUT

http://localhost:8080/api/products/1
{
"request": {
"method": "PUT",
"url": "/api/products/1",
"bodyPatterns": [{
"equalToJson": "{ \"id\": 1, \"name\":
\"new product\", \"creator\": \"tester\",
\"createTime\": \"2015-09-07\" }",
"ignoreArrayOrder" : true,
"ignoreExtraElements" : true
}]
},
"response": {
"status": 200,
"body": "Update successfully.",
"headers": {
"x-token": "
xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
}
}

3) DELETE

http://localhost:8080/api/products/1
{
"request": {
"method": "DELETE",
"url": "/api/products/1"
},
"response": {
"status": 204,
"headers": {
"x-token": "
xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
}
}

4)URL Matching

http://localhost:8080/api/products/1(2/3…)
{
"request": {
"method": "GET",
"urlPattern": "/api/products/[0-9]+"
},
"response": {
"status": 200
}
}

5)Query参数匹配

http://localhost:8080/api/products?
search=china
{
"request": {
"method": "GET",
"urlPath": "/api/products",
"queryParameters": {
"search": {
"contains": "chin"
}
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"body": "{ \"id\": 7, \"name\": \"shan
zai\", \"from\":\"China\" },{ \"id\": 7, \"name\":
\"shan zai\", \"from\":\"China(RPC)\" }"
}
}

6)模拟错误

{
"request": {
"url": "/unknown.html",
"method": "GET"
},
"response": {
"status": 404,
"headers": {
"Content-Type": "text/html; charset=utf-
8"
}
}
}

7)设置响应延时

{
"request": {
"method": "GET",
"url": "/delayed"
},
"response": {
"status": 200,
"bodyFileName": "response.json",
"headers": {
"Content-Type": "application/json",
"Cache-Control": "max-age=86400"
},
"fixedDelayMilliseconds": 2000
}
}

END点赞关注不迷路!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1281056.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Ubuntu20.04安装ROS2

官方参考文章 Ubuntu (Debian) — ROS 2 Documentation: Foxy documentation curl密钥问题 sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg curl: (7) Failed to connect to raw.githubus…

Docker下安装MySQL

如果在Docker下直接拉取MySQL并运行镜像&#xff0c;由于没有指定字符编码集&#xff0c;可能会存在插入中文出现乱码的情况&#xff0c;并且当容器删除后&#xff0c;容器里面存在的数据会丢失&#xff0c;所以在运行容器时应该使用数据卷进行挂载&#xff0c;按照如下步骤操作…

31-WEB漏洞-文件操作之文件包含漏洞全解

31-WEB漏洞-文件操作之文件包含漏洞全解 一、本地包含1.1、无限制包含漏洞文件1.2、有限制包含漏洞文件1.2.1、绕过方法1.2.1.1、%00截断1.2.1.2、长度截断 二、远程包含2.1、无限制包含漏洞文件2.2、有限制包含漏洞文件 三、各种协议流提交流3.1、各协议的利用条件和方法3.1.1…

【Windows】如何实现 Windows 上面的C盘默认文件夹的完美迁移

如何实现 Windows 上面的C盘默认文件夹的完美迁移 1. 遇到的问题 在我想迁移C盘的 下载 和 视频 文件夹的时候&#xff0c;遇到了这样的问题&#xff0c;在迁移之后&#xff0c;我显卡录像的视频还是保存到了C盘默认位置里&#xff0c;以及我迁移了 下载 之后下载的盘依然是在…

XSS漏洞原理

XSS漏洞介绍&#xff1a; 跨站脚本攻击XSS(Cross Site Scripting)&#xff0c;为了不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆&#xff0c;故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码&#xff0c;当用户浏览该页面时&#xff0c;嵌入We…

数据结构 | 查漏补缺之ASL、

目录 ASL 情形之一&#xff1a;二分查找 线索二叉树 哈夫曼树 大根堆 邻接表&邻接矩阵 ASL 参考博文 关于ASL(平均查找长度)的简单总结_平均查找长度asl-CSDN博客 情形之一&#xff1a;二分查找 线索二叉树 参考博文 线索二叉树(线索链表遍历&#xff0c;二叉树…

【拓展】Loguru:更为优雅、简洁的Python 日志管理模块

目录 一、简单介绍 二、安装与简单使用 ​三、常见用法 3.1 显示格式 3.2 写入文件 3.3 json日志 3.4 日志绕接 3.5 并发安全 四、高级用法 4.1 接管标准日志logging 4.2 输出日志到网络服务器 4.2.1 自定义日志服务器 ​4.2.2 第三方库日志服务器 4.3 与pytest结…

LeetCode | 104. 二叉树的最大深度

LeetCode | 104. 二叉树的最大深度 OJ链接 这里需要注意的一点是每次有返回值&#xff0c;需要定义变量来保存上一次的值最后取最高的一方加1 int maxDepth(struct TreeNode* root) {if(root NULL)return NULL;int left maxDepth(root->left);int right maxDepth(root-…

MDETR 论文翻译及理解

题目Abstract1. Introduction2. Method2.1. Background2.2. MDETR2.2.1 Architecture2.2.2 Training 3. Experiments3.1. Pre-training Modulated Detection 预训练调制检测3.2. Downstream Tasks3.2.1 Few-shot transfer for long-tailed detection 4. Related work5. Conclus…

阵列信号处理---均匀线阵和均匀加权线阵

均匀线阵 均匀线性阵列(ULA&#xff1a;Uniform Linear Array)&#xff1a;有N个阵元位于z轴上且具有均匀间距d。 一般都把阵列的中心放在坐标系的原点。如下图 阵元的位置为 p z n ( n − N − 1 2 ) d &#xff0c; n 0 , 1 , … , N − 1 p_{z_n}\big(n-\frac{N-1}{2}\b…

UCore-OS实验Lab0

实验内容&#xff1a;搭建ucore-os的实验环境 实验准备内容&#xff1a;vmware虚拟机&#xff0c;ubuntu22.04镜像&#xff0c;qemu7.0.0源码 ucore代码地址 GitHub - chyyuu/os_kernel_lab at x86-32 实验步骤&#xff1a; 在vmware中安装ubuntu&#xff0c;因为我个人喜欢…

如何保持高能量

精力管理 精力管理对于平衡多项任务和保持热情至关重要。 通过自我积极反馈循环系统培养积极的内心声音。 培养仪式和习惯来控制内心的声音并保持能量。 学习语言带来正能量和宝贵的技能 保持高能量需要自我赋权和体力充电。 经常锻炼有很多好处&#xff0c;包括改善健康…

作业飞翔的鸟

首先创建一个新的Java项目命名为“飞翔的鸟”&#xff0c;并在src中创建一个包命名为“com.qiku.bird"&#xff0c;在这个包内分别创建4个类命名为“Bird”、“BirdGame”、“Column”、“Ground”&#xff0c;并向需要的图片素材导入到包内。 package com.qiku.bird;impo…

[ Linux Audio 篇 ] 音频开发入门基础知识

在短视频兴起的背景下&#xff0c;音视频开发越来越受到重视。接下来将为大家介绍音频开发者入门知识&#xff0c;帮助读者快速了解这个领域。 轻柔的音乐、程序员有节奏感的键盘声、嗡嗡的发动机、刺耳的手提钻……这些声音是如何产生的呢&#xff1f;又是如何传到我们耳中的…

基于Java SSM框架+Vue实现旅游资源网站项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架Vue实现旅游资源网站演示 摘要 本论文主要论述了如何使用JAVA语言开发一个旅游资源网站 &#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述旅游…

IP数据报首部检验和计算方法

图源&#xff1a;360百科 计算首部检验和的步骤&#xff1a;&#xff08;用二进制计算&#xff09; 将IP数据报的首部按照每16位&#xff08;2个字节&#xff09;一组进行分组&#xff0c;这样固定首部能够得到9个这样的16位二进制数&#xff1a; 版本首部长度区分服务&#…

JVM之内存区域(二)

JVM内存区域 JVM 内存区域主要分为线程私有区域【程序计数器、虚拟机栈、本地方法区】、线程共享区域【JAVA 堆、方法区】、直接内存。 线程私有数据区域生命周期与线程相同, 依赖用户线程的启动/结束 而 创建/销毁(在 Hotspot VM 内, 每个线程都与操作系统的本地线程直接映射…

Python必备工具shelve与dbm全面解析!

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 当涉及存储大量数据并且需要高效访问时&#xff0c;Python开发人员常常寻找适当的工具。shelve和dbm模块是Python中用于本地持久化存储数据的两个强大工具。它们允许开发人员以键值对的形式存储数据&#xff0c;…

vue发送请求携带token,拼接url地址下载文件

封装请求 &#xff0c;该请求为普通的get请求 该请求返回值为&#xff1a; 请求成功之后拼接URL地址下载文件 代码块 downTemplateRequest(activeKeys.value).then((res) > {let url http://47.169.168.99:18888/media/${res.data.name};var elink document.createElemen…

vscode问题:此扩展在此工作区中被禁用,因为其被定义为在远程扩展主机中运行

mac按shiftcommandp windows按ctrlshiftP&#xff1a; 将当前项目文件夹添加进去就ok了。