你还在用静态的 Mock 数据吗

简介: 作为前端开发者,在前后端分离的时代下,不能一天到晚追着后端的同学要接口调试,我们可以自己来 Mock 现在的打包工具或者框架基本都支持或者通过第三方插件支持了 Mock 数据的能力。对于写死的静态数据而言,我们可以使用 MockJS 来生成动态的数据,这至少这样看起来更逼真,而且更方便,可以通过 Mock 的表达式来生成指定格式及数量的 JSON 数据。

前言


作为前端开发者,在前后端分离的时代下,不能一天到晚追着后端的同学要接口调试,我们可以自己来 Mock 现在的打包工具或者框架基本都支持或者通过第三方插件支持了 Mock 数据的能力。对于写死的静态数据而言,我们可以使用 MockJS 来生成动态的数据,这至少这样看起来更逼真,而且更方便,可以通过 Mock 的表达式来生成指定格式及数量的 JSON 数据。

废话不多说,先来看官网。进入官网,映入眼帘的是这么几个大字,简洁明了、突出主题。

1682523850(1).png

通过随机数据,模拟各种场景;不需要修改既有代码,就可以拦截 Ajax 请求,返回模拟的响应数据;支持生成随机的文本、数字、布尔值、日期、邮箱、链接、图片、颜色等;支持支持扩展更多数据类型,支持自定义函数和正则

他的特性也在官网标注出来了

前后端分离、增加单元测试的真实性、开发无侵入、用法简单、方便扩展、数据类型丰富……


使用方法


我们先来看使用方法,下一节再看语法。使用Mockjs的时候可以有两种方式,页面直接引入、node环境使用,node中可以在文件中运行也可以跑一个nodeServer来提供数据。

页面

使用script标签引入mockjs

<script src="http://mockjs.com/dist/mock.js"></script>
复制代码

然后就可以使用Mockjs进行数据模拟了,语法不要关心,后面会讲

<body>
  <script src="http://mockjs.com/dist/mock.js"></script>
  <script>
    let data = Mock.mock({
        "userInfo|4": [{
          "id|+1": 1,
          "name": "@cname",
          "ago|18-28": 25,
          "sex|1": ["男", "女"],
          "job|1": ["web", "UI", "python", "php"]
        }]
      })
      console.log(data);
  </script>
</body>
复制代码

在浏览器打开控制台就可以看见模拟的数据了

1682523874(1).png

Node环境中使用

前端框架开发环境

这里我们以Vue开发环境为例,首先创建一个api.js,引入mockjs(需要npm安装依赖),导出模拟数据,这里可以将mock方法的第一个参数设置为一个url,可以实现上面官网提到的特性——拦截ajax请求

import {mock} from 'mockjs';
export default mock('http://localhost/a', {
  "userInfo|4": [{
    "id|+1": 1,
    "name": "@cname",
    "ago|18-28": 25,
    "sex|1": ["男", "女"],
    "job|1": ["web", "UI", "python", "php"]
  }]
})
复制代码

然后在Vue组件中使用axios等工具来进行ajax请求

<script>
import './services/api1.js'
import axios from 'axios'
export default {
  name: 'App',
  created() {
    axios.get('http://localhost/a').then(res => {
      console.log(res);
    })
  }
}
</script>
复制代码

执行npm run serve,打开控制台,这里看到通过拦截ajax生成的mock数据已经不再是一个简单的数据,而是被包装成了一个比较像请求响应的对象

1682523899(1).png

Node服务端

这里使用比较轻量化的服务端框架express来模拟服务端响应,在src目录下创建一个server目录,新建一个server.js文件,添加内容如下

let express = require('express');
let Mock = require('mockjs');
let app = express(); 
app.use('/user', function (req, res) {
  res.json(Mock.mock({
    'dataStatus': 200,
    "userInfo|4": [{
      "id|+1": 1,
      "name": "@cname",
      "ago|18-28": 25,
      "sex|1": ["男", "女"],
      "job|1": ["web", "UI", "python", "php"]
    }]
  }))
})
app.listen('8090', () => {
  console.log('监听端口 8090')
})
复制代码

为了方便使用可以在package.json中添加启动脚本命令(非必须,可以不需要)

"scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "mock": "node src/server/server.js"
    // 为了方便修改内容可以使用nodemon(需要全局安装)
    // "mock": "nodemon src/server/server.js"
  },
复制代码

启动服务端程序npm run mock,没有添加命令就直接使用node运行js文件

打开运行中的Vue页面,这时候会显示跨域错误

1682523921(1).png

解决办法也很简单,在服务端设置CORS即可,在server.js中添加这段代码,要在所有请求的最前面

app.use(function (req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  res.header('Access-Control-Allow-Headers', 'Content-Type');
  next();
});
复制代码

完成

1682523946(1).png


语法规则


mock中的数据模板由三部分构成:属性名、生成规则和属性值

// 属性名   name
// 生成规则 rule
// 属性值   value
'name|rule': value
复制代码

生成规则有7种格式,对应的含义需要根据属性值类型来确定

  1. 'name|min-max': value
  2. 'name|count': value
  3. 'name|min-max.dmin-dmax': value
  4. 'name|min-max.dcount': value
  5. 'name|count.dmin-dmax': value
  6. 'name|count.dcount': value
  7. 'name|+step': value

string

使用之前的node服务端程序运行

  1. 'name|min-max': string
    通过重复 string 生成一个字符串,重复次数大于等于 min,小于等于 max
  2. 'name|count': string
    通过重复 string 生成一个字符串,重复次数等于 count
app.use('/string', (req, res) => {
  res.json(Mock.mock({
    'dataStatus': 200,
    'stringData|4': [{
      'repeat|1-3': '❤',
      'count|2': '😘'
    }]
  }))
})
复制代码

1682523970(1).png

Number

  1. 'name|+1': number
    属性值自动加 1,初始值为 number
  2. 'name|min-max': number
    生成一个大于等于 min、小于等于 max 的整数,属性值 number 只是用来确定类型。
  3. 'name|min-max.dmin-dmax': number
    生成一个浮点数,整数部分大于等于 min、小于等于 max,小数部分保留 dmindmax 位。
app.use('/number', (req, res) => {
  res.json(Mock.mock({
    'dataStatus': 200,
    'numberData|4': [{
      'selfIncreasing1|+1': 1,
      'selfIncreasing2|+2': 1, // 递增2
      'randomNumber1|1-100': 1, // 随机1-100
      'randomNumber2|50': 1, // 固定50
      'floatNumber1|1-100.1-4': 1, // 整数位1-100随机,小数位长度在1-4之间
      'floatNumber2|100.5': 1 // 整数位固定100,小数点后固定4位
    }]
  }))
})
复制代码

1682523994(1).png

Boolean

  1. 'name|1': boolean
    随机生成一个布尔值,值为 true 的概率是 1/2,值为 false 的概率同样是 1/2。
  2. 'name|min-max': value
    随机生成一个布尔值,值为 value 的概率是 min / (min + max),值为 !value 的概率是 max / (min + max)
app.use('/boolean', (req, res) => {
  res.json(Mock.mock({
    'dataStatus': 200,
    'booleanData|4': [{
      'boolean1|1': true,
      'boolean2|1-4': true
    }]
  }))
})
复制代码

1682524027(1).png

Object

  1. 'name|count': object
    从属性值 object 中随机选取 count 个属性。
  2. 'name|min-max': object
    从属性值 object 中随机选取 minmax 个属性。
app.use('/object', (req, res) => {
  const obj = {
    name: 'king',
    age: 12,
    sex: '男',
    No: 6666166
  }
  res.json(Mock.mock({
    'dataStatus': 200,
    'objectData|4': [{
      'object1|1': obj,
      'object2|1-4': obj
    }]
  }))
})
复制代码

1682524058(1).png

Array

  1. 'name|1': array
    从属性值 array 中随机选取 1 个元素,作为最终值。
  2. 'name|+1': array
    从属性值 array 中顺序选取 1 个元素,作为最终值。
  3. 'name|min-max': array
    通过重复属性值 array 生成一个新数组,重复次数大于等于 min,小于等于 max
  4. 'name|count': array
    通过重复属性值 array 生成一个新数组,重复次数为 count
app.use('/array', (req, res) => {
  const arr = [1, 2, 3, 4]
  res.json(Mock.mock({
    'dataStatus': 200,
    'arrayData|4': [{
      'order1|1': arr,
      'order2|+1': arr,
      'interval1|1-4': arr,
      'count1|2': arr,
    }]
  }))
})
复制代码

1682524082(1).png

RegExp

  1. 'name': regexp
    根据正则表达式 regexp 反向生成可以匹配它的字符串。用于生成自定义格式的字符串。
app.use('/regexp', (req, res) => {
  res.json(Mock.mock({
    'dataStatus': 200,
    'regexp|6': [{
      'phone': /^(?:(?:\+|00)86)?1(?:(?:3[\d])|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\d])|(?:9[189]))\d{8}$/,
      'caoNo': /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-HJ-NP-Z](?:((\d{5}[A-HJK])|([A-HJK][A-HJ-NP-Z0-9][0-9]{4}))|[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳])$/
    }]
  }))
})
复制代码

1682524103(1).png

占位符

  1. @ 来标识其后的字符串是 占位符
  2. 占位符 引用的是 Mock.Random 中的方法。
  3. 通过 Mock.Random.extend() 来扩展自定义占位符
app.use('/placeholder', (req, res) => {
  res.json(Mock.mock({
    'dataStatus': 200,
    'placeholderData|4': [{
      id: '@guid',
      name: '@cname',
      color: '@color',
      title: '@ctitle',
      content: '@cparagraph'
    }]
  }))
})
复制代码

1682524127(1).png

更多的占位符内容如下

Type Method
Basic boolean, natural, integer, float, character, string, range, date, time, datetime, now
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
Helper capitalize, upper, lower, pick, shuffle
Miscellaneous guid, id

到此为止Mock相关的大部分知识点已经列出来了,更多用法或者api的请看官网示例

相关文章
|
6月前
|
人工智能 测试技术 API
Eolink创建临时服务mock接口数据——无限制那种非常带劲
Eolink创建临时服务mock接口数据——无限制那种非常带劲
56 1
|
前端开发
什么是 Mock 测试?掌握 Mock 测试的核心原理
Mock 的意思就是,当你很难拿到源数据时,你可以使用某些手段,去获取到跟源数据相似的假数据,拿着这些假数据,前端可以先行开发,而不需要等待后端给了数据后再开发。
|
缓存 测试技术
podam mock 对象部分字段没有赋值问题
本文主要分析使用 podam mock 对象时,部分字段无法自动赋值的原因,并给出解决方案。
|
8天前
类的实例化过程在ES6中是如何优化的?
类的实例化过程在ES6中是如何优化的?
|
2月前
|
存储 缓存 NoSQL
webFilter实现mock接口
这段代码实现了一个名为 `MockFilter` 的类,继承自 `WebFilter` 接口,用于处理 HTTP 请求和响应。它通过从 Redis 缓存中获取配置信息来决定是否使用模拟数据或缓存数据来响应请求。如果开启了生产模式或关闭了模拟和缓存功能,则直接放行请求。否则,它会检查请求体并根据配置返回相应的模拟或缓存数据。同时,该过滤器支持对响应结果进行处理,并将结果存储回 Redis 中。
|
4月前
|
测试技术
详解单元测试问题之处理@Mock注解时mock对象的创建如何解决
详解单元测试问题之处理@Mock注解时mock对象的创建如何解决
44 1
|
4月前
|
测试技术
详解单元测试问题之@InjectMocks注入mock对象如何解决
详解单元测试问题之@InjectMocks注入mock对象如何解决
211 1
|
6月前
thinkphp5.1全局异常类封装
thinkphp5.1全局异常类封装
57 0
thinkphp5.1全局异常类封装
|
6月前
|
JSON 前端开发 JavaScript
如何使用Mock.js来模拟后端接口
如何使用Mock.js来模拟后端接口
91 0
Echarts公用代码的变量统一封装调用
Echarts公用代码的变量统一封装调用
60 0