mock 快速入门
基本概念
问题的起源:前后端分离
在前后端开发的时候,前端的数据基本都是通过api请求获取到的,但是后端可能在开发的时间上与前端不一致,这就导致前端常常需要等待后端提供接口,等待会耗去很多开发时间,所以我们经常做的方式就是自己模拟数据(假数据时代)。
比如写个定时器返回一个数据对象,或者使用一个json文件,去模拟请求。
但是这些其实都并不方便,每次都要自己去写一堆数据,如果是json格式还不能for循环,以及一些随机数据,最重要的是这些代码最终都得删除,因为耦合在业务代码中,而且我们的请求并不是真正的请求代码,最终在后端接口出来后我们还得改一遍代码。
难道就不能前端模拟的效果和真实请求一样,后端接口出来后,我通过环境变量判断一下,然后就可以直接测试了,啥代码都不用改。
为此,阿里妈妈团队开发了一个js库:mock.js
顺带吐槽一下:阿里出品,必定孤儿,19年最后一次更新至此,再无音讯,去年官方文档还能打开,现在域名都没了。
骂归骂,目前好像没有对应竞品进行替换。
使用的方式
项目中直接安装mock
最简单的就是在项目中直接安装mock.js;然后自己创建js文件,引入该库,然后写一堆配置就可以, 这个配置中你需要写一个api地址,比如我请求是https://www.a.com/api/test
,那么你的配置中也得写这个地址。
mock会拦截xhr请求,如果地址能够匹配到,那么就会将自己编写的mock数据作为api结果返回,但是需要注意,由于是拦截xhr请求,所以你无法在浏览器network中看到请求记录,因为没有真实发出去请求。
先看看例子:
npm install mockjs
安装完毕我们创建一个mock的js文件,用于处理我们的mock请求
import Mock from "mockjs";
Mock.setup({
timeout: '300-500' //获取结果的延迟
});
const Random = Mock.Random;
Mock.mock('http://www.baidu.com/api/datadown', res => {
let list = [];
for (let i = 0; i < 10; i++) {
let listobj = {
id: Random.id(),
title: Random.ctitle(5, 10),
}
list.push(listobj);
}
return list;
});
最终,我们在main.js
中将其引入即可。
//mock
require("./mock");
mock会自动拦截axios的请求,然后模拟数据返回,axios就像正常一样使用即可。
github地址:Mock
wiki文档:wiki
由于官网死了,所以很多文档阅读并不方便,wiki文档将就看看吧!
事实上mock衍生了很多种使用方式,比如我们的mock不是一个真实请求,我们可以利用vue cli本身的node服务来搭建一个自己的mock api服务,这个就属于高阶用法了,它本质就是实现了一个server服务来创建api接口,不再是拦截xhr请求了,这种方式只是用到了mock的一些虚拟数据的方法。
高阶用法
vue cli 本身是基于webpack的,那么它的node服务也是基于webpack-dev-server,那么webpack-dev-server本身提供了一个中间件的接口,它类似于我们的axios拦截器,我们可以在拦截器里面对数据和请求做各种操作,而这个中间件接口的提供,我们可以编写自己的一些基于server的方法,比如路由,在后端中,路由其实就是我们常用的api地址。
我看了下文档,但是没有具体的实操,vue cli中提供了一个before的属性,它接受一个函数,函数接一个参数,参数为server的实例对象,可以通过该对象挂载我们的路由。
vue.config.js
import Mock from "mockjs";
//mock模拟一个数据
const data = Mock.mock({
id: "@id()",
username: "@cname()",
email: "@email()"
})
module.exports = {
devServer: {
before(app) {
//挂载一个路由
app.use("/api/user", (req, res) => {
res.json(data);
});
}
}
}
看这个写法,这个server服务应该是express框架
此时我们请求接口:http://localhost:8080/api/user
就会获取到我们mock生成的data数据,此时浏览器里也有对应的network记录。
vue cli官方文档对这个before的介绍好像消失了,只是说了一句所有 webpack-dev-server
的选项都支持,我去webpack文档看了下,好像有一个新的属性叫:setupMiddlewares
,通过该属性可以自由执行自定义的函数和中间件。
如果实操发现上述代码无法正确使用,可以考虑是不是api更新了,webpack文档:setupMiddlewares
缺点
说了那么多,mockjs也不是没有缺陷的,我总结下我趟过的坑。
- mock拦截xhr请求是破坏性的,基本上重写了xhr,这就导致我们即便没有mock数据,只要引入了mockjs就会导致xhr被重写,重写带来了不可预估的问题,其中我们的下载文件进度函数就会出现问题,我记得是。
- mock请求的方式无法浏览器network中查看记录
- 通过编写server中间件的方式可以实现api服务,也有network记录,但是耦合度非常高,明明都是相同的使用代码,多个项目无法很好的复用。
估计还有很多缺点,但是重点应该就是这几个了,所以,现在常见的mock都是自己搭建一个可视化mock服务,比如:
搭建单独的mock server
由于现在我也只是试水使用,咱们使用的Yapi搭建还挺复杂的,也懒得在搬运一套部署方法了,官方和百度都有提供详细的文档,我们就简单聊聊,东西都是可视化,我们品味下思想即可。
搭建一个单独的mock服务,服务众多项目,这也是现在业界常见的做法,解决了n多痛点:
- 完整的代码解耦,前端直接发起真实api请求
- 更加灵活,可视化选项+自定义编辑增加可用度
- ...
可以说mock server是现在的一大趋势,但是也并不是一记万能药,它依旧会存在一些问题,比如:
一开始前后端约定好了一些数据格式,也mock配置好,但是后面由于一些问题,后端不得不修改接口,怎么办?
前端还在使用旧的mock,或者说,后面切真实api接口时,接口的变动,没有实时的更新mock服务,这种情况肯定也会有的。
所以这个痛点在现在的一些综合工具上被想办法解决:ApiPost、ApiFox、Eolink,他们都想通过编写一个测试接口用例的同时将mock数据也一并处理了,这样当接口更新时,只需要保持测试接口的正确,mock也会同时更新到。
在Eolink中甚至将通知功能加入,当我改变一个接口时,可以发起一个通知告诉使用这个接口的人,我已经更新了。
但是很遗憾的是,这些工具并不成熟,还有很多很多的问题,而且也不是用爱发电,人家开发也要赚钱,所以有时候我们因为种种原因并不能真正的用上这些东西。
总结
综上所述,想必大家已经明白什么是mock了,它能做什么,怎么做,有哪些方式。
mock本身并不难,但是文档确实烂,如果想要熟练的使用,还得多看看文档,记那些拗口的用法,但是这并不是全部,但是它只是一种工具,略懂即可。
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿站点。未经许可,禁止转载。
暂无评论数据