什么是Mock?为什么要使用Mock呢?
1、前言
在日常开发过程中,大家经常都会遇到:新需求来了,但是需要跟第三方接口来对接,第三方服务还没好,我们自己的功能设计如何继续呢?这里,给大家推荐一下Mock方案。
2、场景示例
2.1、场景一:公司外部间的接口调用
我们都知道,联调外部接口,往往都需要申请测试环境,而申请外部测试环境的时间往往都很长、会耗费很多精力。当然,一般都是项目经理去协调的,但是作为有担当的开发人员,不可能在这个空窗期摸鱼划水吧。不然,等环境下来之后,可就是自己苦日子的开始,毕竟,不催工期的项目经理还是少见的。
2.2、场景二:公司内部之间的接口调用
曾经有一个项目需要我们配合另一个部门一起做。需求宣讲完后就是定排期,然后我们就问合作部门:“这几个接口什么时候可以联调?”
因为合作部门还在赶另外一个项目,便回复道:“我们先一起对接口,等忙完手头这个项目,再给出排期可以吗?”
然后我们催促道:“那也得给出一个具体的上线计划啊?”
在我们的催促下,合作部门终于给出了一个日期。
过了几天,合作部门手头的项目出现了延期,又跑过来跟我们说:“我们可能晚几天才能提供那些接口。”
因为需要与对方交互的接口的功能迟迟未动,我们也不敢释放人手,担心人手释放后,项目又立马启动,开发人员好不容易熟悉了新项目又要回来做这个。
为此,我们坐在一起商量了一个解决思路:
3、解决思路
我们希望有一个 Mock 接口服务,它能提供与正式服务的 URI、出入参一样的接口,区别是主机名或者 URL 的前缀不一样。
在开发和测试过程中,我们都连接上 Mock 服务。等到接口或环境搭建好后,我们无须修改代码,通过一个简单的配置切换即可让服务连接到真实接口服务,然后通过一些简单的回归测试即可实现上线,大大提升了开发效率,此时整体的系统架构如下图所示:

不过,如果我们想实现这一思路,可就一点不简单了,因为他包含了Mock服务端和Mock服务客户端调用设计。
4、Mock服务端设计
先说下在Mock服务端设计过程中,都需要满足哪些需求?
4.1、Mock接口支持返回动态字段数据
比如有个接口输入的参数为userId、orderid、redirectUrl,如下所示:
输出参数为success和startTime,如下所示:
我们希望每次调用这个Mock接口时,startTime都返回当前时间,如:
{
success:true,
startTime:2023-11-12 12:45:02
}
4.2、Mock接口支持一些简单逻辑
在测试过程中,我们会通过不同的测试用例走完不同的流程。
紧接着上面的例子,比如我们希望调用 Mock 接口传入的 UserID 是 10001,那么 Mock 接口返回的 success 值为 True,否则为 False,而后系统会根据不同的 success 值进入不同的流程。
4.3、Mock接口支持回调
在实际开发工作中,有很多联调接口需要异步回调,比如上面的例子中,如果返回的 success 值是 True,我们希望过一段时间回调 Redirect URL。
4.4、Mock接口支持规则校验
我们希望通过添加一些规则让这个 Mock 服务对传入的参数进行校验,比如校验 UserID 是否为数字、OrderID 是否为 15 位数字、Redirect URL 是否为 URL……
4.5、Mock接口支持接口文档导入
这一点比较特别,比如某些团队在设计接口文档时,直接将接口定义放在 Wiki 上;而某些团队直接写在 Java 代码中,再通过 Swagger 生成在线接口文档。
对于前者,我们要求定义接口时,直接将接口文档放在新的 Mock 服务上。而对于后者,因为不想改变他们的习惯,所以最终 Mock 服务需要支持 Swagger 文档导入。
根据以上五点需求,我们开始在市面上找一些合适的开源框架,并发现市面上收费的接口文档管理工具有 Apizza、Eolinker,免费的有 YAPI 和 RAP2,出于各种原因的考虑,最终我们决定在 YAPI 和 RAP2 中进行选择。
这里我们可以看一下YAPI和RAP2对比:
通过表中的内容对比,很明显YAPI更符合我们的需求。因此,在Mock服务端设计过程中,我们选择基于YAPI进行二次开发。
5、Mock服务客户端调用设计
说完Mock服务端,接下来我们看看调用Mock服务客户端时,都需要考虑什么?
5.1、Mock服务如何支持基于二进制流的接口调用?
因为历史原因,有些服务间调用使用 Spring Cloud Feign ,而有些服务间调用使用基于二进制流序列化的 RPC(当然是基于 TOP 协议)。
我们知道,如果服务间的通讯是基于二进制流而不是 JSON,就没办法在 YAPI 上通过简单的界面定义输入输出参数了,且 YAPI 也不支持二进制流的调用,此时我们的解决方案如下图所示:
在上面框架中,我们添加了一个拦截器,它会拦截所有服务间调用的请求,并增加一个判断。如果访问的地址是 Mock 服务,我们就使用 HTTP 协议,并且通过 JSON 进行序列化和反序列,这样问题就解决了。
这里,我们需要补充一点:曾经,我还碰到过一些第三方接口使用 XML 格式(很多银行的接口就是这样),最终我们决定先不支持自定义XML格式的接口,因为改造 YAPI 的工作量实在太大。
5.2、Mock服务客户端如何简单切换Mock与真实服务?
这里,我们需要考虑以下两种情况:
-
对于第三方接口,我们只需在配置中将第三方接口的 host 改为 Mock 服务的 host 即可。 -
对于微服务间的调用,我们知道 Spring Cloud 中的微服务定义都是服务级别,但是在实际开发的场景中,我们需要使用接口级别的 Mock,比如我们开发的 operationService,它依赖 productService 的几个接口。因此,在新项目中,我们还需要在 productService 中新增几个接口,且它们必须调用 Mock 服务的接口,而原先的接口继续调用真实的 productService 中原来已经做好的接口。此时,我们需要在配置中心增加 2 个配置项:mock.apis 和 mock.host,每次服务间调用时,先判断调用的 URI 是否在 mock.apis 字符串列表中,如果在,则让它调用 mock.host 这台机器。特别说明一点:关于这点,曾经我们也出过错。因为在上线时配错了 mock.apis 和 mock.host,导致线上环境使用了 Mock 服务的情况,所以我们需要多考虑下面这点。
5.3、如何预防线上环境使用Mock服务?
对于此问题,我们做了一个检查代码:在服务启动时,先判断当前的环境名称,如果是 prod(线上环境),先判断 mock.apis 中是否有值,有值的话提示异常。然后扫描所有的 properties 配置,如果配置中包含 Mock 服务地址,则说明有些地方配置了 Mock 服务的调用,也提示异常。
到这里,整体的 Mock 调用方案就完成了。
以上,就是关于Mock服务端与客户端的设计与实现思路,有更好的方案或思路, 可以联系我哦:
微信公众号:服务端技术精选
淘宝小店:淘宝小店
个人小网站:小网站
本文由 mdnice 多平台发布
相关文章:

什么是Mock?为什么要使用Mock呢?
1、前言 在日常开发过程中,大家经常都会遇到:新需求来了,但是需要跟第三方接口来对接,第三方服务还没好,我们自己的功能设计如何继续呢?这里,给大家推荐一下Mock方案。 2、场景示例 2.1、场景一…...

elementui表格自定义指令控制显示哪些列可以拖动
Vue.directive(tableBorder, function (el, {value}) {// value允许传字符串数字和数组el.classList.add(z_table_hasBorder)let hasStyle el.querySelector(style)if(hasStyle){hasStyle.remove()}let style document.createElement(style)let str .z_table_hasBorder .el…...

Motion Plan之搜素算法笔记
背景: 16-18年做过一阵子无人驾驶,那时候痴迷于移动规划;然而当时可学习的资料非常少,网上的论文也不算太多。基本就是Darpa的几十篇无人越野几次比赛的文章,基本没有成系统的文章和代码讲解实现。所以对移动规划的认…...
新中新身份证阅读器驱动下载sdk DKQ-A16D
读取操作 int nRet;string sMsg "";IDCardData idcardData new IDCardData();byte[] ctmp new byte[255];ReadCardAPI.Syn_SetPhotoPath(1, ref ctmp);setupDataFormate(1);nRet ReadCardAPI.Syn_OpenPort(Main_Form.m_iPort);if (nRet 0){DateTime startTime …...

世界坐标系,相机坐标系,像素坐标系转换 详细说明(附代码)
几个坐标系介绍,相机内外参的回顾参考此文。 本文主要说明如何在几个坐标系之间转换。 本文涉及: 使用相机内参 在 像素坐标系 和 相机坐标系 之间转换。使用相机外参(位姿)在相机坐标系 和 世界坐标系 之间转换。(qw,qx,qy,qz,…...

计算机毕业设计 基于SpringBoot的企业内部网络管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解
博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…...
CISP模拟试题(三)
免责声明 文章仅做经验分享用途,利用本文章所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,作者不为此承担任何责任,一旦造成后果请自行承担!!! 1. 人们对信息安全的认识从信息技术安全发展到信息安全保障,主要是由于: A.为了更好地完成组…...

前端调取摄像头并实现拍照功能
前言 最近接到的一个需求十分有意思,设计整体实现了前端仿 微信扫一扫 的功能。整理了一下思路,做一个分享。 tips: 如果想要实现完整扫一扫的功能,你需要掌握一些前置知识,这次我们先讲如何实现拍照并且保存的功能。 一. wind…...
android —— 阴影效果和跑马灯效果Textview
1、带阴影的TextView ①、 android:shadowColor“color/black” 设置阴影颜色,需要与shadowRadius一起使用 ②、android:shadowRadius“3.0” 设置阴影模糊程度,设为0.1会变成字体颜色,建议设置3.0 ③、android:shadowDx“10” 设置阴影在水…...

多态语法详解
多态语法详解 一:概念1:多态实现条件 二:重写:三:向上转型和向下转型1:向上转型:1:直接赋值:2:方法传参3:返回值 2:向下转型 一:概念 1:同一个引…...

Python大数据之linux学习总结——day11_ZooKeeper
ZooKeeper ZK概述 ZooKeeper概念: Zookeeper是一个分布式协调服务的开源框架。本质上是一个分布式的小文件存储系统 ZooKeeper作用: 主要用来解决分布式集群中应用系统的一致性问题。 ZooKeeper结构: 采用树形层次结构,ZooKeeper树中的每个节点被称为—Znode。且树…...

C语言——函数的嵌套调用
#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>void new_line() {printf("Hello\n"); }void three_line() {int i0;for(i0;i<3;i){new_line();} }int main() {three_line();return 0; }...

4种经典的限流算法与集群限流
0、基础知识 1000毫秒内,允许2个请求,其他请求全部拒绝。 不拒绝就可能往db打请求,把db干爆~ interval 1000 rate 2; 一、固定窗口限流 固定窗口限流算法(Fixed Window Rate Limiting Algorithm)是…...

网工内推 | 国企、港企网工,年底双薪,NA以上认证即可
01 中航期货有限公司 招聘岗位:信息技术部-网络工程师 职责描述: 1、负责总部、分支机构、外联单位网络的日常运维、故障和应急处置,特别是定期监测设备的运行状态,对存在隐患的地方及时发现改正,保持网络稳定通畅&am…...

【华为HCIP | 华为数通工程师】刷题日记1116(一个字惨)
个人名片: 🐼作者简介:一名大三在校生,喜欢AI编程🎋 🐻❄️个人主页🥇:落798. 🐼个人WeChat:hmmwx53 🕊️系列专栏:🖼️…...

软考-高级-系统架构设计师教程(清华第2版)【第7章 系统架构设计基础知识(263~285)-思维导图】
软考-高级-系统架构设计师教程(清华第2版)【第7章 系统架构设计基础知识(263~285)-思维导图】 课本里章节里所有蓝色字体的思维导图...

⑩⑥ 【MySQL】详解 触发器TRIGGER,协助 确保数据的完整性,日志记录,数据校验等操作。
个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~ 个人主页:.29.的博客 学习社区:进去逛一逛~ 触发器 ⑩⑥ 【MySQL】触发器详解1. 什么是触发…...

数据结构与算法编程题3
长度为n的顺序表,删除线性表所有值为x的元素,使得时间复杂度为O(n),空间复杂度为O(1) #include <iostream> using namespace std;typedef int ElemType; #define Maxsize 100 #define OK 1 #define ERROR 0 typedef struct SqList {E…...
Go基础面经大全(持续补充中)
Go基础 1. 基础特性 Go的优势 天生支持并发,性能高。 单一的标准代码格式,比其他语言更具可读性。 自动垃圾收集机制比Java和Python更有效,因为它与程序同时执行。 Go数据类型 int, string, float, bool, array, slice, map, channel, p…...
uniapp heckbox-group实现多选
文章目录 html 代码JS 代码 混了业务逻辑,谨慎观看 html 代码 <view><!--可滚动视图区域。用于区域滚动 --><scroll-view :style"{ height: clientHeight px }" :scroll-top"scrollTop" scroll-y"true"scrolltouppe…...
Redis 中的 5 种数据类型和示例场景
Redis 作为一款高性能的键值对数据库,凭借其丰富的数据类型,在缓存、消息队列、排行榜等众多场景中发挥着重要作用。本文将详细介绍 Redis 的 5 种核心数据类型,并结合示例场景和代码,让你快速掌握它们的使用方法。 一、String&am…...

TCP/IP协议精华总结pdf分享
hi ,大家好,应小伙伴们的要求,上次分享了个人的一些学习和职场经验,其中网络协议PDF文档是我之前学习协议的时候总结一些精华知识,网络属于基本功,是互联网必备知识,我深信掌握好核心20%知识&am…...

MySQL高可用集群
https://dev.mysql.com/doc/mysql-shell/8.4/en/mysql-innodb-cluster.html 1 什么是MySQL高可用集群 MySQL高可用集群:MySQL InnoDB ClusterInnoDB Cluster是MySQL官方实现高可用读写分离的架构方案,包含以下组件 MySQL Group Replication:简…...

定时任务:springboot集成xxl-job-core(二)
定时任务实现方式: 存在的问题: xxl-job的原理: 可以根据服务器的个数进行动态分片,每台服务器分到的处理数据是不一样的。 1. 多台机器动态注册 多台机器同时配置了调度器xxl-job-admin之后,执行器那里会有多个注…...

95套HTML高端大数据可视化大屏源码分享
概述 在大数据时代,数据可视化已成为各行各业的重要需求。这里精心整理了95套高端HTML大数据可视化大屏源码,这些资源采用现代化设计风格,可帮助开发者快速构建专业的数据展示界面。 主要内容 1. 设计风格与特点 采用…...
AI Agent企业级生产应用全解析
在企业级应用中,AI Agent 的核心是将其从一个对话模型转变为一个自主决策和执行的自动化工作流引擎。这需要一个精密的 “Agent 执行框架”(Agent Orchestration Framework) 来协调 LLM 的推理、外部工具的调用、记忆管理和自我反思。 AI Ag…...

Mysql库的操作和表的操作
Mysql库和表的操作 库的操作1.查看数据库列表2.创建数据库3.使用数据库4.查看当前在那个数据库中5.显示数据库的创建语句6.修改数据库7.删除数据库8.备份和恢复数据库9.查看数据的连接情况(简单来说就是查看有多少人使用你的数据库) 表的操作1.创建表2.查看表结构3.修改表本身(…...

【Elasticsearch】Elasticsearch 核心技术(一):索引
Elasticsearch 核心技术(一):索引 1.索引的定义2.索引的命名规范3.索引的增、删、改、查3.1 创建索引3.1.1 创建空索引 3.2 删除索引3.3 文档操作3.3.1 添加/更新文档(指定ID)3.3.2 添加文档(自动生成ID&am…...
Mybatis框架各配置文件主要内容详解(二)
ResultMap解决了数据库字段与实体类之间不一致导致的问题 <!--resultMap:设置自定义映射属性:id:表示自定义映射的唯一标识type:查询的数据要映射的实体类的类型子标签:id:设置主键的映射关系result&…...
1.3HarmonyOS NEXT统一开发范式与跨端适配:开启高效跨设备应用开发新时代
HarmonyOS NEXT统一开发范式与跨端适配:开启高效跨设备应用开发新时代 在HarmonyOS NEXT的技术体系中,统一开发范式与跨端适配是两大关键特性,它们为开发者打破了设备边界,极大地提升了开发效率与应用体验。本章节将深入探讨方舟…...