接口测试 基于 springboot+vue 的接口测试平台(三)-- 动态 mock

Blue · 2021年01月27日 · 最后由 Blue 回复于 2021年03月08日 · 9695 次阅读

转眼一个月又过去了,这次主要 mock 功能搞了很久,网上资料主要集中在后端单元测试的 mock,以及前端自己项目的 mock

后端:

  • moco:需要另起服务,响应参数需要在 json 文件里
  • mockit:主要单元测试使用

前端:

  • mock.js 只能模拟返回,不能当成真的请求,且网上大部分帖子说的都是如何模拟前端项目的单一接口,而我想做的是只要是个接口就可以 mock
  • Express+mock.js 这个应该可以满足要求,但是 Express 要另起服务,觉得很麻烦

在茫茫帖子中找到了一个 springboot 动态 mock 能够实现我的想法:https://blog.csdn.net/lt326030434/article/details/108649878

最后决定:后端使用 springboot 自己做服务,前端使用 mock.js 写写规则

springboot service 关键代码:

public void dynamicMock(HttpServletRequest request, HttpServletResponse response) {
    String requestPath = request.getServletPath();
    LambdaQueryWrapper<ApiMock> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(ApiMock::getMockUrl, requestPath);
    ApiMock mock = baseMapper.selectOne(wrapper);
    if (mock != null) {
        OutputStream outputStream = null;
                    //解决浏览器乱码
        response.setHeader("content-type", "text/html;charset=utf-8");
        try {
            outputStream = response.getOutputStream();
            if (mock.getStatus() == 0) {
                byte[] dataByteArr = mock.getResponseBody().getBytes();
                outputStream.write(dataByteArr);
                response.setStatus(mock.getResponseCode());
            }else {
                String error = "您未开启mock状态";
                byte[] dataByteArr = error.getBytes();
                outputStream.write(dataByteArr);
            }
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

通过 status 状态来控制 mock 的开关,response.setStatus 可以返回自己想要的响应码

前端代码:

import Mock from "mockjs"

var dataMock = Mock.mock(this.jsonData);
this.apiMock.responseBody = JSON.stringify(dataMock)

前端通过 Mock.js 把模板数据转换,然后传给数据库保存(这里用的有点担心,怕数据太大影响数据库的性能,但是暂时没有找到更好的办法)

最后的效果图:

mock 地址是 baseUrl + apiId + 接口路径,方法和响应码可以自己定义,Mock.js 的模板也可以自己定义,但必须要是 json 格式

做完这个功能问安卓开发怎么样,答曰:baseUrl 太麻烦了,apiId 也不是固定的,总之就是麻烦,可是大家不都是这么做的么😂

共收到 21 条回复 时间 点赞

yapi 不香么?

Blue #20 · 2021年01月27日 Author
陈恒捷 回复

就想挑战下,而且用户有特殊需求也可以立马响应

Blue 回复

针对你前面说的,你现在的 mock 还缺几个实际使用的时候要做的功能点:

1、选择性接口 Mock,比如只是 Mock 某个这次新开发的接口,其他还是走老接口。可以参照下 https://www.mock-server.com/proxy/configuring_sut.html#port_forwarding ,没配置 mock 的都自动转发给真实服务,有配置的才返回 Mock。
2、同一个接口支持多个 mock,方便多人协作
3、安卓开发说麻烦,主要原因还是本身 mock 最好是基于接口文档自动生成或服务端搞好一个可用的蓝本,而不是还需要客户端开发自己去从零配置。这方面 yapi 做得会比较好,但对于你这个单独的平台来说成本略高。

基于 swagger and 网关上面做网络接口层的 mock 应该更通用,也容易共用。 你这种方式做模块层的 stub?

Blue #17 · 2021年01月27日 Author
陈恒捷 回复

第 1 点的话,我目前新接口和老接口都可以 mock,mock 功能只是这个接口的一个功能,也可以录入、调试生成响应体和响应头,这样做的好处是一些老页面修改了,需要比较多的数据的时候,就直接使用 mock 接口,不用测试自己造数据

第 2 点之前没想到,我问下开发需不需要,需要的话就去试试去,毕竟我们前端开发就一个,安卓开发就两个
第 3 点,也是最头痛的,真的是参考 yapi,只是没有实现它的 json-schema 功能,后期会加上这个功能,使用方式也是这么使用的。

Blue #6 · 2021年01月27日 Author
xiaoyu 回复

我们开发的语言是 python 呢,他们不用 swagger。。基于网关的导入,后期想做这个功能,比如从 charles 和 fiddler 生成 har 格式后,导入到平台

Blue 回复

可能我没表述清楚,我说的第一点是支持局部 mock,比如登录接口就走真实的,查看某个页面的数据接口才走 mock 。这期间客户端不需要改什么,由 mock 平台控制。不知道现在有支持了吗?

Blue #14 · 2021年01月27日 Author
陈恒捷 回复

😢 可以做到这么智能了么,没有做这个功能,我仔细看看你的链接去,谢谢

Blue 回复

并不是很智能呀,其实就是你的 mock 匹配算法里,加个兜底的转发策略。

对应你前面 service 代码,就是在 if (mock != null) {if (mock.getStatus() == 0) { 对应加上else逻辑,else 逻辑里面做兜底的转发给真实服务。

实际业务一般只会有 1-2 个新加或修改的接口要 Mock,很多核心接口都是没动的。如果这个时候客户端全量切到 mock 平台,核心接口没有配置 mock,那就没法走通流程了。

另一位同学说的做在网关层也是很不错的方案,客户端啥都不用改,只需要平台自己去改网关配置就行。这样你说的客户端嫌改自己配置麻烦的事情也解决了。

Blue 回复

网关现在可以通过配置和操作支持各种转发,可以定制在网关上; apisix kong 都挺强大的,并且可以和其他平台对接。

Blue #11 · 2021年01月27日 Author
xiaoyu 回复

谢谢,我去调研下,一下子开放了我好多思路

以前也搞过一个 mock 平台,使用整体 anyproxy +springboot + thymeleaf +k8s 的方式
1、前端配置规则,包括 req、resp 的字符串、正则、jsonpath 的修改后透传和 mock,
2、java 与 anyproxy 实时交互,将规则推送到 anyproxy 代理。
3、anyproxy 捕获到命中规则的请求,将请求转发到 server 端进行修改、替换,anyproxy 接收到修改后 req、resp 后再根据规则进行 mock 或者进行透传下去。
3、多人使用这块为了防止互相影响,提前封装了 anyproxy 的镜像和代理脚本,平台调用 k8s 接口,给每个使用者一个独立代理,这样规则互不影响
其实与传统代理比较,只是代理工具相当于部署在了 server 端,和丰富了更多的 mock 规则。
后来又加上了流量录制和回放,解析 ingress 规则将流量归类到对应的服务下,对服务设置一些通用校验和根据流量格式生成一些健壮性测试用例进行回放。

Blue #9 · 2021年01月29日 Author
hacrun 回复

哥,开源吗,想学习下

19 年的时候做了同样的事情,实现方式都一样,不过我们当时配合了接口自动化测试做的,相对更便捷一点儿,例如:
1、动态 mock 管理;
2、实现 mock 返回值的动态修改(当然目前很多 mock 可以通过规则匹配实现动态返回);
3、实现动态增加 mock 接口;
4、通过 jmeter+Java+mock 平台 +Jenkins 实现接口自动化以及测试报告推送微信公众号等功能;
5、集成其他测试小工具:MD5、json 格式化、kafka 消息推送/消费 等等。

Blue #15 · 2021年02月01日 Author
sky 回复

跟我做的差不多呢

mock server 了解一下,这个是我最终的技术选型,希望能帮到你

兔子 回复

有链接不

@ 恒温 呀,难得大佬提问,附上链接:https://www.mock-server.com/#what-is-mockserver

wiremock 不香吗

Blue #2 · 2021年03月08日 Author
兔子 回复

很久没来了,你这么说我就去看你的开源代码去了呀,先谢谢了

Blue #1 · 2021年03月08日 Author
codes 回复

我看看,谢谢

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册