1、Mock.js数据生成器
1.1 解决什么问题
问题:
前后端分离项目,前端和后端人员都是根据API文档进行项目开发的,不应该直接相互依赖,前端人员不应该等待后端开发好接口再进行测试,既然不依赖后端接口,那么前端人员应该如何测试呢?
解决:
可以通过模拟数据生成器,通过一定规则(API文档)生成模拟数据接口,提供给前端人员测试。
1.2 什么是Mock.js
-
Mock.js可以生成随机数据,拦截Ajax请求。
-
通过拦截Ajax请求,根据模板生成并返回模拟数据,让前端人员独立于后端人员进行,帮助编写单元测试。
-
Mock.js的作用:
-
前后端分离
让前端开发人员独立于后端进行开发。
-
增加单元测试的真实性
通过生成随机模拟数据,模拟各种场景。
-
开发无入侵
不需要修改既有代码,就可以拦截Ajax请求,返回模拟的响应数据。
-
用法简单
符合直觉的接口。
-
数据类型丰富
支持随机生成文本、数字、布尔值、日期、邮箱、链接、图片、颜色等等。
-
方便拓展
支持拓展更多数据类型,支持自定义函数和正则。
-
1.3 安装Mock.js
通过npm
命令就可以安装Mock.js:
npm install mockjs
1.4 入门案例与语法规范
1.4.1 入门案例
需求:生成4条列表数据。
效果如下:
{
"menberList": [
{
"id": 1,
"name": "staryjie"
},
{
"id": 1,
"name": "staryjie"
},
{
"id": 1,
"name": "staryjie"
},
{
"id": 1,
"name": "staryjie"
}
]
}
编码实现:
-
新建
E:\Gogs\VueProject\mockjs-demo
目录,通过命令提示符窗口进入该目录,初始化项目。npm init -y
-
安装Mock.js
npm install mockjs
-
新建
demo1.js
,代码如下:const Mock = require('mockjs') const data = Mock.mock({ //定义数据生成规则 'menberList|4': [{ 'id': 1, 'name': 'staryjie' }] }) console.log(JSON.stringify(data, null, 2))
-
运行该文件,查看效果
node .\demo1.js
1.4.2 语法规则
- Mock.js的语法规范包括两部分
- 数据模板定义规范(Data Template Definition,DTD)
- 数据占位符定义规范(Data Placeholder Definition, DPD)
1.5 数据模板定义规范 DTD
数据模板中的每个属性由3部分构成:属性名、生成规则、属性值:
// '属性名|生成规则': 属性值
'name|rule': value
注意:
- 属性名和生成规则之间通过竖线
|
分隔。 - 生成规则是可选的,生成规则有7种格式:
'name|min-max': value
'name|count': value
'name|min-max.dmin-dmax': value
'name|min-max.dcount': value
'name|count.dmin-dmax': value
'name|count.dcount': value
'name|+step': value
- 生成规则的含义需要依赖属性值的类型才能定。
- 属性值中可以含有
@占位符
。 - 属性值指定了最终值的初始值和类型。
1.5.1 属性值是字符串 String
'name|count': string
,通过重复string
生成一个字符串,重复次数等于``count`。'name|min-max': value
,通过重复string
生成一个字符串,重复次数大于等于min
,小于等于max
。
代码:
const Mock = require('mockjs')
const data = Mock.mock({
//定义数据生成规则
'menberList|4': [{
'id': 1,
'name|1-3': 'staryjie', // 随机生成生成1-3个staryjie
'phone|11': '8', // String生成11个8
}]
})
console.log(JSON.stringify(data, null, 2))
执行效果:
1.5.2 属性值是数字 Number
'name|+1': number
,属性值自动加1,初始值为``number`。'name|min-max': number
,生成一个大于等于min
、小于等于max
的整数,属性值number
只是用来确定值的类型。'name|min-max.dmin-dmax': number
,生成一个浮点数,整数部分大于等于min
、小于等于max
,小数部分保留dmin
到dmax
位。
代码:
const Mock = require('mockjs')
const data = Mock.mock({
'memberList|4': [{
'id|+1': 1, // Number,自增1,初识值为1
'name|1-3': 'tcc', // String,随机生成1-3个重复'tcc'
'phone|11': 1, // String,生成11个1
'age|1-120': 20, // Nmuber,随机生成1-120之间的数字
'salary|6000-10000.1-3': 1, // Number,随机生成6000-10000的1-3位小数的数字
}]
})
console.log(JSON.stringify(data, null, 2))
执行效果:
1.5.3 属性值是布尔型 Boolean
'name|1': boolean
,随机生成值为true
或者false
,两者概率都是1/2。'name|min-max': value
,随机生成一个布尔值,值为value
的概率为min / (min + max)
,值为!value
的概率为max / (min + max)
。
代码:
const Mock = require('mockjs')
const data = Mock.mock({
'memberList|4': [{
'id|+1': 1, // Number,自增1,初识值为1
'name|1-3': 'tcc', // String,随机生成1-3个重复'tcc'
'phone|11': 1, // String,生成11个1
'age|1-120': 20, // Nmuber,随机生成1-120之间的数字
'salary|6000-10000.1-3': 1, // Number,随机生成6000-10000的1-3位小数的数字
'status|1': true, // Boolean,生成true或false的概率都是1/2。
'open|2-4': true, // Boolean,生成true的概率是2/(2+4),生成false的概率是4/(2+4)
}]
})
console.log(JSON.stringify(data, null, 2))
执行效果:
1.5.4 属性值是对象 Object
'name|count': object
, 从属性值object
中随机选取count
个属性。'name|min-max': object
,从属性object
中随机挑选min
到max
个值。
代码:
const Mock = require('mockjs')
const data = Mock.mock({
'memberList|4': [{
'id|+1': 1, // Number,自增1,初识值为1
'name|1-3': 'tcc', // String,随机生成1-3个重复'tcc'
'phone|11': 1, // String,生成11个1
'age|1-120': 20, // Nmuber,随机生成1-120之间的数字
'salary|6000-10000.1-3': 1, // Number,随机生成6000-10000的1-3位小数的数字
'status|1': true, // Boolean,生成true或false的概率都是1/2。
'open|2-4': true, // Boolean,生成true的概率是2/(2+4),生成false的概率是4/(2+4)
'order|2': {
id: 1,
name: '订单1',
price: 999
}, // 在对象中随机抽取2个属性进行返回
'order|2-3': {
id: 1,
name: '订单1',
price: 999
}, // 在对象中随机抽取2-3个属性进行返回
}]
})
console.log(JSON.stringify(data, null, 2))
执行效果:
1.5.5 属性值是数组 Array
'name|min-max': array
,通过重复属性值array
生成一个新数组,重复次数大于等于min
,小于等于max
。'name|count': array
,通过重复属性值array
生成一个新数组,重复次数为count
。
代码:
const Mock = require('mockjs')
const data = Mock.mock({
'memberList|2-5': [{ // Array,随机生成2-5个数组中的元素
'id|+1': 1, // Number,自增1,初识值为1
'name|1-3': 'tcc', // String,随机生成1-3个重复'tcc'
'phone|11': 1, // String,生成11个1
'age|1-120': 20, // Nmuber,随机生成1-120之间的数字
'salary|6000-10000.1-3': 1, // Number,随机生成6000-10000的1-3位小数的数字
'status|1': true, // Boolean,生成true或false的概率都是1/2。
'open|2-4': true, // Boolean,生成true的概率是2/(2+4),生成false的概率是4/(2+4)
'order|2': {
id: 1,
name: '订单1',
price: 999
}, // 在对象中随机抽取2个属性进行返回
'order|2-3': {
id: 1,
name: '订单1',
price: 999
}, // 在对象中随机抽取2-3个属性进行返回
}]
})
console.log(JSON.stringify(data, null, 2))
执行效果:
1.5.6 值是正则表达式 RegExp
'name': regexp
,根据正则表达式regexp
反向生成可以匹配它的字符串。用于生成自定义格式的字符串。
注意:regexp是没有引号的
代码:
const Mock = require('mockjs')
const data = Mock.mock({
'memberList|4': [{
'id|+1': 1, // Number,自增1,初识值为1
'name|1-3': 'tcc', // String,随机生成1-3个重复'tcc'
'phone|11': 1, // String,生成11个1
'age|1-120': 20, // Nmuber,随机生成1-120之间的数字
'salary|6000-10000.1-3': 1, // Number,随机生成6000-10000的1-3位小数的数字
'status|1': true, // Boolean,生成true或false的概率都是1/2。
'open|2-4': true, // Boolean,生成true的概率是2/(2+4),生成false的概率是4/(2+4)
'order|2': {
id: 1,
name: '订单1',
price: 999
}, // 在对象中随机抽取2个属性进行返回
'order|2-3': {
id: 1,
name: '订单1',
price: 999
}, // 在对象中随机抽取2-3个属性进行返回
'idCard': /\d{15}|\d{18}/ // 随机生成15位或者18位的身份证号码
}]
})
console.log(JSON.stringify(data, null, 2))
执行效果:
1.6 数据占位符定义规范 DPD
Mock.Random是一个工具类,用于生成各种随机数据。
Mock.Random类中的方法在数据模板中成为{占位符},书写格式为@占位符(参数 [, 参数])
。
占位符的格式为:
'属性名': @占位符
Mock.Random类中提供的完整方法(占位符)如下:
Type(类型) | Method(占位符) |
---|---|
Basic | boolean , natural (自然数,大于等于 0 的整数), integer , float , character , string , range (整型数组) |
Date | date (年月日), time (时分秒), datetime (年月日时分秒) |
Image | image, dataImage |
Color | color |
Text | paragraph, sentence, word, title, cparagraph, csentence, cword, ctitle |
Name | first, last, name, cfirst, clast, cname |
Web | url, domain, email, ip, tld |
Address | area, region |
Miscellaneous | guid, id |
1.6.1 基本类型占位符
-
随机生成基本数据类型的数据
常用占位符:
- natural
- integer
- string
- float
- boolean
-
代码:
const Mock = require('mockjs') const data = Mock.mock({ 'empList|3': [{ 'id|+1': 1, 'name': '@string', 'price': '@float', 'status': '@boolean', }] }) console.log(JSON.stringify(data, null, 2))
-
执行效果:
1.6.2 日期占位符
-
随机生成日期类型的数据
常用占位符:
- date/date(format)
- time/time(format)
- datetime/datetime(format)
-
代码:
const Mock = require('mockjs') const data = Mock.mock({ 'empList|3': [{ 'id|+1': 1, 'name': '@string', 'price': '@float', 'status': '@boolean', 'birthday': '@date', // 默认 yyyy-MM-dd 'entryDate': '@date("yyyy/mm/dd")', // 指定日期格式 yyyy/MM/dd 'createDate': '@datetime', // // 默认 yyyy-MM-dd HH:mm:ss 'updateDate': '@datetime("yyyy/mm/dd HH:mm:ss")', // 指定格式为 yyyy/MM/dd HH:mm:ss }] }) console.log(JSON.stringify(data, null, 2))
-
执行效果:
1.6.3 图像占位符
-
随机生成图片地址,生成的地址在浏览器可以正常打开。
占位符:
- image
-
代码:
const Mock = require('mockjs') const data = Mock.mock({ 'empList|3': [{ 'id|+1': 1, 'name': '@string', 'price': '@float', 'status': '@boolean', 'birthday': '@date', // 默认 yyyy-MM-dd 'entryDate': '@date("yyyy/mm/dd")', // 指定日期格式 yyyy/MM/dd 'createDate': '@datetime', // // 默认 yyyy-MM-dd HH:mm:ss 'updateDate': '@datetime("yyyy/mm/dd HH:mm:ss")', // 指定格式为 yyyy/MM/dd HH:mm:ss 'pic': '@image', }] }) console.log(JSON.stringify(data, null, 2))
-
执行效果:
1.6.4 文本占位符
-
随机生成一段文本
占位符:
- ctitle 随机生成一句中文标题
- csentence(mix?, max?) 随机生成一段中文文本
-
代码
const Mock = require('mockjs') const data = Mock.mock({ 'empList|3': [{ 'id|+1': 1, 'name': '@string', 'price': '@float', 'status': '@boolean', 'birthday': '@date', // 默认 yyyy-MM-dd 'entryDate': '@date("yyyy/mm/dd")', // 指定日期格式 yyyy/MM/dd 'createDate': '@datetime', // // 默认 yyyy-MM-dd HH:mm:ss 'updateDate': '@datetime("yyyy/mm/dd HH:mm:ss")', // 指定格式为 yyyy/MM/dd HH:mm:ss 'pic': '@image', // 图片地址 'title': '@ctitle(3, 6)', // 中文标题(3到6个字) 'content': '@csentence(8, 12)', // 一段中文文本(8到12个字) }] }) console.log(JSON.stringify(data, null, 2))
-
执行效果:
1.6.5 名称占位符
-
随机生成名称。
占位符:
- first 英文名
- last 应为姓
- name 英文姓名
- cfirst 中文名
- clast 中文姓
- cname 中文姓名
-
代码
const Mock = require('mockjs') const data = Mock.mock({ 'empList|2': [{ 'id|+1': 1, 'name': '@string', 'price': '@float', 'status': '@boolean', 'birthday': '@date', // 默认 yyyy-MM-dd 'entryDate': '@date("yyyy/mm/dd")', // 指定日期格式 yyyy/MM/dd 'createDate': '@datetime', // // 默认 yyyy-MM-dd HH:mm:ss 'updateDate': '@datetime("yyyy/mm/dd HH:mm:ss")', // 指定格式为 yyyy/MM/dd HH:mm:ss 'pic': '@image', // 图片地址 'title': '@ctitle(3, 6)', // 中文标题(3到6个字) 'content': '@csentence(8, 12)', // 一段中文文本(8到12个字) 'first': '@first', 'last': '@last', 'name': '@name', 'cfirst': '@cfirst', 'clast': '@clast', 'cname': '@cname', }] }) console.log(JSON.stringify(data, null, 2))
-
执行效果:
1.6.6 网络占位符
-
随机生成URL、域名、IP地址、邮件地址
占位符:
- url(protocol?, host?) 生成url
- protocol:协议,如
http
- host:域名和端口号,如
staryjie.com
- protocol:协议,如
- domain 生成域名
- ip 生成IP
- email 生成email地址
- url(protocol?, host?) 生成url
-
代码:
const Mock = require('mockjs') const data = Mock.mock({ 'empList|2': [{ 'id|+1': 1, 'name': '@string', 'price': '@float', 'status': '@boolean', 'birthday': '@date', // 默认 yyyy-MM-dd 'entryDate': '@date("yyyy/mm/dd")', // 指定日期格式 yyyy/MM/dd 'createDate': '@datetime', // // 默认 yyyy-MM-dd HH:mm:ss 'updateDate': '@datetime("yyyy/mm/dd HH:mm:ss")', // 指定格式为 yyyy/MM/dd HH:mm:ss 'pic': '@image', // 图片地址 'title': '@ctitle(3, 6)', // 中文标题(3到6个字) 'content': '@csentence(8, 12)', // 一段中文文本(8到12个字) 'first': '@first', 'last': '@last', 'name': '@name', 'cfirst': '@cfirst', 'clast': '@clast', 'cname': '@cname', 'url': '@url("https", "api.staryjie.com")', 'domain': '@domain', 'ip': '@ip', 'email': '@email', }] }) console.log(JSON.stringify(data, null, 2))
-
执行效果:
1.6.7 地址占位符
-
随机生成区域、省市县、邮政编码
占位符:
- region 区域。如:华南。
- county(true) 省市县。
- zip 邮政编码。
-
代码:
const Mock = require('mockjs') const data = Mock.mock({ 'empList|2': [{ 'id|+1': 1, 'name': '@string', 'price': '@float', 'status': '@boolean', 'birthday': '@date', // 默认 yyyy-MM-dd 'entryDate': '@date("yyyy/mm/dd")', // 指定日期格式 yyyy/MM/dd 'createDate': '@datetime', // // 默认 yyyy-MM-dd HH:mm:ss 'updateDate': '@datetime("yyyy/mm/dd HH:mm:ss")', // 指定格式为 yyyy/MM/dd HH:mm:ss 'pic': '@image', // 图片地址 'title': '@ctitle(3, 6)', // 中文标题(3到6个字) 'content': '@csentence(8, 12)', // 一段中文文本(8到12个字) 'first': '@first', 'last': '@last', 'name': '@name', 'cfirst': '@cfirst', 'clast': '@clast', 'cname': '@cname', 'url': '@url("https", "api.staryjie.com")', 'domain': '@domain', 'ip': '@ip', 'email': '@email', 'area': '@region', 'address': '@county(true)', 'zipcode': '@zip', }] }) console.log(JSON.stringify(data, null, 2))
-
执行效果: