Mock的方式
- 在client端处数据mock
- 在server端mock(json-server与faker.js)
- 第一种方式拦截了请求的发出,直接返回mock的数据,而第二种方式请求则真实地发出,只是在server端进行route拦截
- 前后端分离的方式,就是在传统开发模式中加了一个node层,这样数据mock完全可以在node server端完成
client mock
- 拦截所有请求
- 进行url规则匹配
- 匹配对的,返回mock数据
- 匹配不对的,走原本流程
mock.js
1.概念
mock.js是一个模拟数据生成器,帮助前后端分离。它可以根据数据模版生成模拟数据,模拟Ajax请求,生成随机数据返回。
2.使用语法
Mock.js 的语法规范包括两部分
- 数据模板定义规范
- 数据占位符定义规范
详细请看:mock.js文档链接
// 记录数据模板。当拦截到匹配 rurl 的 Ajax 请求时,将根据数据模板 template 生成模拟数据,并作为响应数据返回。
Mock.mock( rurl, rtype, function( options ) )
rurl
可选。
表示需要拦截的 URL,可以是 URL 字符串或 URL 正则。例如 /\/domain\/list\.json/、'/domian/list.json'。
rtype
可选。
表示需要拦截的 Ajax 请求类型。例如 GET、POST、PUT、DELETE 等。
template
可选。
表示数据模板,可以是对象或字符串。例如 { 'data|1-10':[{}] }、'@EMAIL'。
function(options)
可选。
表示用于生成响应数据的函数。
options
指向本次请求的 Ajax 选项集,含有 url、type 和 body 三个属性,参见 XMLHttpRequest 规范。
复制代码
示例
Mock.mock('/api/getName', { name: 'Jack', 'age|10-20': 10 });
复制代码
3. 模板语法
1)数据模板定义规范(例举)
'name|min-max': string
Mock.mock({
"string|1-10": "★"
})
// result
{
"string": "★★★"
}
复制代码
'name|count': string
Mock.mock({
"string|3": "★★★"
})
// result
{
"string": "★★★★★★★★★"
}
复制代码
2)Mock.Random Mock.Random 是一个工具类,用于生成各种随机数据。
Mock.Random 的方法在数据模板中称为『占位符』,书写格式为 @占位符(参数 [, 参数]) 。
var Random = Mock.Random
Random.email()
// => "n.clark@miller.io"
Mock.mock('@email')
// => "y.lee@lewis.org"
Mock.mock( { email: '@email' } )
// => { email: "v.lewis@hall.gov" }
复制代码
// Random.datetime()
Random.datetime()
Mock.mock('@datetime')
Mock.mock('@datetime()')
// Random.datetime( format )
Random.datetime('yyyy-MM-dd A HH:mm:ss')
Random.datetime('yy-MM-dd a HH:mm:ss')
Random.datetime('y-MM-dd HH:mm:ss')
Random.datetime('y-M-d H:m:s')
Mock.mock('@datetime("yyyy-MM-dd A HH:mm:ss")')
Mock.mock('@datetime("yy-MM-dd a HH:mm:ss")')
Mock.mock('@datetime("y-MM-dd HH:mm:ss")')
Mock.mock('@datetime("y-M-d H:m:s")')
Mock.mock('@datetime("yyyy yy y MM M dd d HH H hh h mm m ss s SS S A a T")')
//result
// Random.datetime()
"1984-03-11 21:34:12"
"2011-07-11 01:17:12"
"2007-03-25 16:31:51"
// Random.datetime( format )
"2018-01-27 AM 01:57:13"
"98-09-12 pm 21:34:08"
"71-06-03 07:13:40"
"15-1-20 11:58:41"
"1991-09-17 PM 15:41:03"
"99-09-11 am 01:00:15"
"71-03-21 10:16:52"
"14-12-10 16:32:53"
"1976 76 76 09 9 29 29 06 6 06 6 12 12 33 33 184 184 AM am 212796753184"
复制代码
4. 缺点
无法拦截fecth请求
fetch-mock
1. 概念
拦截fecth请求,进行mock数据返回
2. 模板语法
fetchMock.mock(matcher, response)
复制代码
常用:
fetchMock.once() //限制了只被调用一次
fetchMock.restore() //恢复其unstubbed fetch()状态和清除所有数据记录
复制代码
3. 用法
- 安装
npm install mockjs
- 需要安装fetch-mock包
--yarn add fetch-mock
,这个包主要用来包装fetch- 注册mock 拦截信息的,应该是在App入口的位置
if(process.env.__DEV__) {
require('./mock/todolist')
}
复制代码
- 主要增加了mock文件夹,todolist.js是模拟数据
import FetchMock from 'fetch-mock';
FetchMock.mock('*', (url, options) => {
//解析获取opt
if(opt==='9'){
return {
// mock数据
};
}
if(opt==='155'){
return {
// mock数据
};
}
else {
//恢复其unstubbed fetch()状态和清除所有数据记录
FetchMock.restore();
return fetch(url, options);
}
// FetchMock.restore();
// return fetch(url, options);
});
复制代码
3. 项目的业务规则
项目目前情况:同一个url请求,通过opt进行判断调用哪个业务接口,因此无法直接使用url进行区分匹配,需要更详细的判断
实际请求代码
params.opt = opt
let dataString = ''
let index = 0
const keys = Object.keys(params)
keys.forEach((key) => {
if (index != 0) {
dataString += '&'
}
index++
const data = params[key]
const encodeData = encodeURIComponent(data)
dataString += `${key}=${encodeData}`
})
// opt最终会合并到dataString中,因此使用的时候,需要解析
let fetchPromise = fetch(url, {
method: 'post',
body: dataString,
headers: header,
}).then((response) => {
if (response.ok) {
return response.json()
} else {
throw new Error('网络错误')
}
})
复制代码
fetch-mock中
FetchMock.mock('*', (url, options) => {
var dataString = options.body;
var array = dataString.split("&")
var opt;
for (var temp of array) {
var temps = temp.split("=")
var key = temps[0]
var value = decodeURIComponent(temps[1])
if (key === "opt") {
opt = value;
}
}
if (opt === 195) {
// 进行转发请求
} else {
FetchMock.restore();
// 走正常请求
}
})
复制代码
server mock
1. 简单构建一套mock-server
为了更好的分工合作,让前端能在不依赖后端环境的情况下进行开发,其中一种手段就是为前端开发者提供一个 web 容器,这个本地环境就是 mock-server
2. 一个比较好的 mock-server 该有的能力
- 与线上环境一致的接口地址,每次构建前端代码时不需要修改调用接口的代码
- 所改即所得,具有热更新的能力,每次增加修改 mock 接口时不需要重启 mock 服务,更不用重启前端构建服务
- 能配合 Webpack
- mock 数据可以由工具生成不需要自己手动写
- 能模拟 POST、GET 请求
3. 使用json-server模拟服务器API
以 json-server 作为 mock 服务器, mock.js 生成mock 数据,json-server支持各种GET/POST/PUT/DELETE的请求
简单使用
1)安装json-server
npm install -g json-server
2)发起fecth请求
import FetchMock from 'fetch-mock';
//其他路由使用原生fetch
FetchMock.mock('*', (url, options) => {
//opt解析
var array = options.body.split("&")
var opt;
for (var temp of array) {
var temps = temp.split("=")
var key = temps[0]
var value = temps[1]
if(key==='opt'){
opt = value
}
}
//opt匹配,发出fecth请求,进行mock数据返回
if(opt==='9'){
FetchMock.restore();
return fetch('http://localhost:53000/data');
}
if(opt==='155'){
FetchMock.restore();
return fetch('http://localhost:53000/list');
}
else {
FetchMock.restore();
return fetch(url, options);
}
// FetchMock.restore();
// return fetch(url, options);
});
复制代码
3)生成一个json.js文件,结合mock.js动态生成模拟数据
var Mock = require('mockjs');
module.exports = () => {
// 使用 Mock
var datas = Mock.mock({
data:
{
//mock数据
}
,
list:{
//mock数据
"error": 0,
"message": "success",
'capitalDetails|30': [
{
//mock.js动态生成模拟数据
"summary": "@ctitle",
"time": "@datetime",
}
]
}
});
// 返回的data会作为json-server的数据
return datas;
};
复制代码
4)启动json-server ,把一个js文件返回的数据托管成web服务
json-server --watch --port 53000 json.js
成功时控制台输出:
shubing-mac:mock admin$ json-server --watch --port 53000 json.js
\{^_^}/ hi!
Loading json.js
Done
Resources
http://localhost:53000/data
http://localhost:53000/list
Home
http://localhost:53000
Type s + enter at any time to create a snapshot of the database
Watching...
复制代码
缺点
每次修改数据模版时,必须重新启动mock服务器
4.使用Faker.js
自动生成大量fake的json数据,作为后端数据