Skip to main content

第16章 接口Mock

从本章开始结合实战经历讲解开发运维场景。这些经历中包含思路的探索和实践,看完这些思路后,相信在进行自研项目时一定能大大提高工作效率。

联调阻塞问题

16.1 业务场景:第三方服务还没完成,功能设计如何继续

在设计新零售系统时,联调阶段经常会碰到各种意外,其中最典型的两个场景:

与公司外部之间的调用

联调外部接口往往需要先申请测试环境,而申请测试环境的时间一般都很长,会耗费很多精力。

比如有一次需要对接一个第三方支付接口,系统自身的功能需求实现后,对接第三方支付接口的功能还迟迟没有动工。组员不断催商务,商务不断催第三方支付的联系人,第三方支付的联系人一直说在走流程,最终仅仅一个第三方支付接口的测试环境就等了3周

公司内部之间的接口调用

曾经有一个项目需要团队配合另一个部门一起做。需求宣讲完后就是定排期,然后团队就问合作部门:"这几个接口什么时候可以联调?"

因为合作部门还在赶另外一个项目,便回复道:"我们先一起对接口,等忙完手头这个项目,再给出排期可以吗?"

因为需要与对方交互的功能迟迟未动,团队也不敢释放人手,担心释放后项目又立即启动,好不容易熟悉新项目后又要回来做这个项目。

16.2 解决思路

项目组希望有一个Mock接口服务,它能提供与正式服务的URL、出入参一样的接口,区别是主机名或者URL的前缀不一样。

Mock服务切换

在开发和测试过程中,大家的服务都连接上Mock服务进行联调。等到接口或环境搭建好后,无须修改代码,通过一个简单的配置切换即可让服务连接到真实接口服务,然后通过一些简单的回归测试即可实现上线,能大大提升开发效率。

16.3 Mock服务端设计

Mock服务端需要满足以下需求:

16.3.1 Mock接口支持返回动态字段数据

比如有一个接口输入的参数为userID、orderID和redirectURL,输出的参数为success和startTime,每次调用这个Mock接口时,startTime都需要返回当前时间

16.3.2 Mock接口支持一些简单的逻辑

在测试过程中,会通过不同的测试用例走完不同的流程。比如,若调用Mock接口传入的userID是10001,那么Mock接口返回的success值为true,否则为false,而后系统会根据不同的success值进入不同的流程。

16.3.3 Mock接口支持回调

在实际开发工作中,有很多联调接口需要异步回调,比如如果返回的success值是true,希望一段时间后回调redirectURL。

16.3.4 Mock接口支持规则校验

希望通过添加一些规则让这个Mock服务对传入的参数进行校验,比如校验userID是否为数字、orderID是否为15位数字、redirectURL是否为URL等。

16.3.5 Mock服务支持接口文档导入

对于将接口定义放在Wiki上的团队,要求定义接口时直接将接口文档放在新的Mock服务上;对于直接写在Java代码中通过Swagger生成在线接口文档的团队,最终Mock服务需要支持Swagger文档导入。

16.3.6 Mock服务端实现框架

YAPI功能特性

根据以上需求,项目组寻找合适的开源框架。收费的接口文档管理工具有Apizza、Eolinker,免费的有YAPI和RAP2。

对比项YAPIRAP2
动态字段支持支持
简单逻辑支持部分支持
回调支持需二次开发不支持
规则校验支持支持
Swagger导入支持支持
社区活跃度

通过对比发现YAPI更贴合需求,开发人员只需改动一个小功能即可满足所有需求。因此,在Mock服务端的实现过程中,最终基于YAPI进行二次开发。

16.4 Mock服务客户端调用设计

客户端设计

16.4.1 Mock服务如何支持基于二进制流的接口调用

因为历史原因,系统中有些服务间调用使用Spring Cloud Feign,而有些服务间调用使用基于二进制流序列化的RPC。

如果服务间的通信基于二进制流而不是JSON,就无法在YAPI上通过简单的界面定义来输入、输出参数,且YAPI也不支持二进制流的调用。

解决方案:添加一个拦截器,它会拦截所有服务间调用的请求,并增加一个判断。如果访问的地址是Mock服务,就使用HTTP协议,并且通过JSON进行序列化和反序列化。

补充说明

有些第三方接口会使用XML格式(很多银行的接口就是这样),最终项目组决定先不支持自定义XML格式的接口,因为改造YAPI的工作量实在太大。

16.4.2 Mock服务客户端如何简单切换Mock与真实服务

这里要考虑以下两种情况:

场景解决方案
第三方接口在配置中将第三方接口的Host改为Mock服务的Host即可
微服务间调用在配置中心增加mock.apismock.host配置项,调用时判断URL是否在mock.apis列表中

对于微服务间的调用,Spring Cloud中的微服务定义都是服务级别,但是在实际开发的场景中,需要使用接口级别的Mock。每次服务间调用时,先判断调用的URL是否在mock.apis字符串列表中,如果在,则让它调用mock.host这台机器。

16.4.3 如何预防线上环境使用Mock服务

重要

曾经因为在上线时配错了mock.apis和mock.host,导致线上环境使用了Mock服务!

预防措施:编写检查代码,在服务启动时:

  1. 先判断当前的环境名称,如果是prod(线上环境),就先判断mock.apis中是否有值,有的话提示异常
  2. 扫描所有的properties配置,如果配置中包含Mock服务地址,则说明有些地方配置了Mock服务的调用,也提示异常

16.5 小结

整体方案总结

Mock服务上线使用后,如果第三方服务或者其他团队的接口还没有准备好,可以直接根据接口文档配置Mock接口,并且所有测试人员都可以基于这些Mock接口展开测试。测试成功后,就可以释放团队成员,安排他们开展其他项目。

等第三方服务或其他团队的接口完成后,再抽调部分成员回到该项目进行简单联调和回归测试,从而实现了系统快速上线。

方案优势

优势说明
不等待第三方无需等待第三方接口或其他团队接口就绪
并行测试所有测试人员可基于Mock接口并行测试
快速回归接口就绪后只需简单回归测试即可上线
人员释放测试成功后可释放团队成员做其他项目

下一章将讲解如何解决测试环境不够用的问题:一人一套测试环境