在开发后端的应用中,我们使用postman来测试接口,观察和验证前后端之间的数据传递是否正常。
在开发前端的应用中,我们使用Mock.js来模拟后端服务,以便进行前端业务逻辑的开发和测试(以前使用json-server也很方便)。
一般情况下,个人开发或者小团队开发是前后端分离的,各自完成后再集中组合测试,之前都是各自独立完成。虽然现在的开发者一般都是全栈(全端)的,但是提供一个完整的后端服务也不是一件容易的事情,建立与需求对应的数据库,然后使用开发工具进行开发,这些都需要时间。
现在的前端请求基于Axios的居多,而mock.js刚好基于XMLHttpRequest,它就是对 XMLHttpRequest 对象进行了拦截和重写来实现的提供数据的功能,它可以有效地拦截Axios请求并返回开发者所需要的数据,在前端测试完成后,删除或者注释掉mock.js提供的服务,那么就可以与后端的服务无缝集成了。
需要注意的是,如果是fetch请求的服务,那么mock.js并不能拦截,因为fetch并不基于XMLHttpRequest。(使用fetch-mock拦截)
mock.js的官网地址:Mock.js
一、在node中进行模拟
⑴新建一个目录;
⑵在该目录下安装mock.js;
npm install mockjs
⑶编写测试脚本并命名为test01.js;
//引入mock.js
const Mock=require("mockjs");
//创建模拟数据
const data=Mock.mock({'arr|1-5':[{'id|+1':1,'name':'@Cname','SFZ':generateSFZ() }]
})
//输出数据
//console.log(data);
//输出JSON格式的数据
console.log(JSON.stringify(data,null,4));function generateSFZ() {// 生成随机的省、市、县代码const regionCode = Math.floor(Math.random() * 1000).toString().padStart(6, '0');// 生成随机的出生日期const birthDate = randomDate(new Date(1970, 0, 1), new Date());// 生成随机的4位数字const randomCode = Math.floor(Math.random() * 10000).toString().padStart(4, '0');// 拼接身份证号码const idNumber = regionCode + birthDate + randomCode;return idNumber;
}// 生成指定范围内的随机日期
function randomDate(start, end) {return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime())).toISOString().slice(0, 10).replace(/-/g, '');
}
⑷运行获取返回的结果;
nodemon test01.js
⑸得到如下数据;
{"arr": [{"id": 1,"name": "吴磊","SFZ": "000988197304198263"},{"id": 2,"name": "白秀兰","SFZ": "000988197304198263"},{"id": 3,"name": "姚秀兰","SFZ": "000988197304198263"},{"id": 4,"name": "胡霞","SFZ": "000988197304198263"},{"id": 5,"name": "高刚","SFZ": "000988197304198263"}]
}
二、在网页中进行模拟
大多数情况下,我们都是在网页中进行模拟。在网页中实现的操作比较简单,在网页中加载mock.js(将mock.js下载到本地),然后就可以直接使用。
网页代码:
<!DOCTYPE html>
<html><head><meta charset="UTF-8"></meta><title>MockJS</title><script src="mock.js"></script></head>
<body> <textarea id="MyOutput" rows="10" cols="20"></textarea><button id="myButton">执行</button><script>const data=Mock.mock({'arr|1-5':[{'id|+1':1,'name':'@Cname','SFZ':generateSFZ() }]})function generateSFZ() {// 生成随机的省、市、县代码const regionCode = Math.floor(Math.random() * 1000).toString().padStart(6, '0'); // 生成随机的出生日期const birthDate = randomDate(new Date(1970, 0, 1), new Date()); // 生成随机的4位数字const randomCode = Math.floor(Math.random() * 10000).toString().padStart(4, '0'); // 拼接身份证号码const idNumber = regionCode + birthDate + randomCode; return idNumber;}// 生成指定范围内的随机日期function randomDate(start, end) {return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime())).toISOString().slice(0, 10).replace(/-/g, '');}// 获取按钮和多行文本框的 DOM 元素const Mybutton = document.getElementById("myButton");const Myoutput = document.getElementById("MyOutput");// 给按钮添加点击事件监听器Mybutton.addEventListener("click", function() {//将结果输出到多行文本框中Myoutput.value = JSON.stringify(data,null,4);});</script>
</body>
</html>
网页结果显示:
三、注意
1、拦截Axios请求,关键是请求地址的一致。
//先进行mock拦截
Mock.mock('请求地址',{'data|5':[{'name':'@cname','age':'@integer'}]
});//发送Axios请求
axios.request({method:'get',url:"请求地址"
}).then(res=>{ console.log(res.data); }
);
这里需要注意的是拦截请求应该写在前面。
mockserver和mock并不是同一产品,使用mockserver相当于提供web服务。
2、Mock.js的语法规范包括数据模板定义和数据占位定义。
数据模板定义:'属性名|生成规则':属性值。
支持函数和正则表达式很有用,根据开发需求可以使用函数或者正则表达式来完成,很方便灵活。
3、数据定义的占位符号@以及搭配,可以使用系统内置的名称来完成相应的数据定义,支持字符串的拼接。
例如下面的代码:
const Mock=require("mockjs");
const data=Mock.mock({'arr|3':[{'id':"@id",'name':"@cname",'email':"@email",'address':"@region",'integer':"@integer",'color':"@color",'datetime':"@datetime",'title':"@ctitle",'ip':"@ip",'url':"@url",}]
})
输出结果数据:
{"arr": [{"id": "130000199504118134","name": "侯平","email": "r.hosye@bpawnvjnn.sy","address": "西北","integer": 245581220630184,"color": "#f279a5","datetime": "1987-04-09 05:16:52","title": "技解马性石","ip": "159.228.60.56","url": "prospero://koimjk.bb/suwiijnm"},{"id": "34000020030915787X","name": "汪军","email": "b.tlkhrvmuu@htjgelx.gi","address": "华东","integer": 1558748183328488,"color": "#79c8f2","datetime": "2017-01-17 04:17:01","title": "正件做几二程","ip": "134.237.192.134","url": "cid://nounwtt.in/dppmbsr"},{"id": "450000200502184074","name": "龙娜","email": "j.uvvggjcr@ehnsid.sa","address": "华北","integer": 3322039815551336,"color": "#ebf279","datetime": "2008-03-17 01:28:18","title": "查标设民你题","ip": "97.194.44.215","url": "prospero://jbuxf.lc/qgrymgj"}]
}
4、Mock.js模拟动态返回的数据。
下面是在网页中模拟动态Mock.js返回动态数据。
<!DOCTYPE html>
<html><head><meta charset="UTF-8"></meta><title>MockJS</title><script src="mock.js"></script><script src="axios.min.js"></script></head>
<body> <script>let userInfo = {}; //拦截请求并模拟数据Mock.mock('http://127.0.0.1:9123/api/user', 'post', function (options) {// 获取请求参数const params = JSON.parse(options.body); // 根据请求参数动态返回数据const userId = params.UserId;console.log(userId);switch(userId){case 1:userInfo = { id: 1, name: 'Dawn' };break;case 2:userInfo = { id: 2, name: 'Vue' }; break;case 3:userInfo = { id: 3, name: 'JavaScript' };break;default:userInfo = { id: 0, name: 'error' };break; };return {code: 200,data: userInfo};});axios.defaults.baseURL = 'http://127.0.0.1:9123';// 发起一个axios请求axios.post('/api/user', { UserId: 2 }).then(response => {console.log('Response data:', response.data);}).catch(error => {console.error('Error:', error);});</script>
</body>
</html>
5、带有图形界面的FastMock更简单和容易使用,地址:FastMock,可以根据个人情况下载使用。