如何使用 Mock

Mock 能做什么?

1.API 没开发好,使用 Mock 快速对接

在产品经理发布需求后,前后端同学先根据功能需求出一份 API 文档,然后再按照 API 文档并行开发。

不依赖后端提供数据的情况下,如何让前端独立于后端进行开发呢?

使用 Mock,你可以在开发环境代码内置 Mock,拦截请求,模拟真实 API 返回。如果公司使用了接口管理平台,文档发布的时候可以还通过平台生成 Mock API 直接对接。

2.为测试提供数据

使用Mock 假数据替代我们想控制但控制困难的部分

例如

  • 某些 API 依赖其他 API 的返回值,使用 Mock 方便的对返回值进行改变,测试不同场景下 API 的表现。
  • 某个 API 特别慢,可以暂时用 Mock 代替它,快速调通整个场景测试流程。

3.方便快速建立功能原型

敏捷开发过程中,调整需求是很常见的。通过 Mock 可以快速建立功能原型,直观的看到业务逻辑,方便产品调整需求,还可以使用假数据对系统进行演示。

Mock 部署

记录以下三种方案,各有千秋。

1.将 Mock 写到代码变量中,哪里需要写哪里

例如

image

优点

  • 成本低,使用简单,只需要学习 Mock.js 模板语法。
  • 不受网络影响。
  • 改动 Mock 能够快速看到效果。

缺点

  • Mock 代码与业务代码耦合高,上线容易遗漏测试代码,为代码偷偷埋下一颗地雷。
  • 无法快速响应文档改动,保持 Mock 返回数据与文档一致。
  • 只有前端开发人员能用到 Mock,无法与其他部门人员协同工作。
  • 没有 API 请求,不够真实。

2. Mock.js 拦截请求

使用 Mock.mock 函数拦截请求

var data = Mock.mock("https://www.baidu.com", {
    "string|1-10": "★", //随机生成 1-10 个字符串"★"
})
var request = new XMLHttpRequest();
request.open("GET", "https://www.baidu.com", true);
request.send();
request.onreadystatechange = function () {
    if (request.readyState === 4 && request.status === 200) {
        console.log(request.responseText)
    }
}

控制台输出

image

优点

  • 成本低,使用简单,学习 Mock.js 模板语法、 Mock.mock 函数。
  • 不受网络影响。
  • 改动 Mock 能够快速看到效果。

缺点

  • 对于 RESTful 风格的 API,需要写正则匹配请求地址。
  • Mock 代码与业务代码仍存在耦合,可以独立一个 Mock 文件夹,上线构建时不打包进业务代码。
  • 无法快速响应文档改动,保持 Mock返回数据与文档一致;
  • API 请求被 Mock 拦截,没有实际发送,不够真实。
  • 只有前端开发人员能用到 Mock,无法与其他部门人员协同工作。

3. Mock Server

和实际请求 HTTP API 没有区别,API 的响应值不是真实从数据库获取的数据,而是 Mock 生成的假数据。

一般是后端人员维护 Mock Server,他们改动 API 的时候同步改动 mock,前端不用考虑 Mock,只需要变更请求地址。

优点

  • 维护文档的人员可以维护 Mock,文档改动同时改动 Mock,响应迅速!
  • 协同方便,测试人员可以利用开发建立的 Mock 提前建立单元测试。
  • 使用工具的话可以通过用户界面管理 Mock 数据。

缺点

  • 需要花钱(部署服务器的钱或者 Sass 付费)
  • 需要选择靠谱的工具,否则使用工具的提高的效率跟不上你帮工具找 Bug 的速率
  • 额外管理 Mock Server,前端无法快速改变 Mock 值。

自己搭建

针对各种语言的部署方案教程丰富,例子不举了,自个儿搜。

平台部署

Eolinker

在线网站,无需部署。免费版本支持 3 人协作,超过 3 人需要开通付费版。

可以管理 API 文档,系统提供的 Mock 功能通过 API 文档返回值信息快速生成随机数据。支持设置触发条件(请求头、请求体),根据不同的触发条件得到不同的返回值。

Easy Mock

没使用过,支持在线(在线版本可能不够稳定),也支持本地部署。

Mock 数据生成规范

可以通过两种方式告诉 Mock 如何生成数据,一种是自定义规则的数据模板,一种是占位符,提供一些常见的随机值,例如·图片、邮箱、人名等。

1.数据模板定义规范(Data Template Definition,DTD)

先看一个示例,Mock.mock 函数根据相应的数据模板生成相应 JSON。

Mock.mock({
 "string|1-10": "★",//随机生成 1-10 个字符串"★"
 "string2|3": "★",//固定生成 3 个字符串"★"
 "number|+1": 202,//每次请求自增 1,初始值为 202
 "number2|1-100.1-10": 1,//生成一个浮点数,整数部分1-100,小数部分保留1-10 位。。
 "boolean|1-2": true,//值为 true 的概率是 1/(1+2),值为 false 的概率同样是 2/3。
 "regexp": /[a-z][A-Z][0-9]/,//随机生成满足正则的字符串
 "object|2": {
   "310000": "上海市",
   "320000": "江苏省",
   "440000":"广东省"
 },//对象中随机选取 2 个属性,生成对象
 "array|1": [ "AMD","CMD"],//数组中随机选取 1 个元素,最终生成值
 "arrayRepeat|3": ["AMD","CMD"],//重复数组元素 3 次,最终生成数组
 "date":"@date"//生成随机日期
})

生成结果

{
 "string": "★★",
 "string2": "★★★",
 "number": 202,
 "number2": 71.73566,
 "boolean":true,
 "regexp": "qS8",
 "absolutePath": "★★ demo",
 "object": {
   "310000": "上海市",
   "440000": "广东省"
 },
 "array": "AMD",
 "arrayRepeat": ["AMD","CMD", "AMD","CMD",AMD","CMD"],
 "date":"1980-12-19"
}
image

数据模板中的每个属性由 3 部分构成:属性名、生成规则、属性值:

// '属性名|生成规则':属性值
'name|rule': value

针对不同的属性值,生成规则的意义也不一样,有的生成规则是概率(Boolean),有的生成规则是重复。具体的意义可以查阅 Mock.js 官方文档

2.数据占位符定义规范(Data Placeholder Definition,DPD)

占位符是 mock 提供一些常用的随机数据例如随机生成的图片、邮箱、人名等。

用法1: 直接使用

Mock.mock('@date')//1982-10-15
Mock.Random.date()//1997-12-31

用法2: 在数据模板中使用

 Mock.mock({
  "date":"@date",//随机日期
  "float":"@float",//随机浮点数
  "name":"xxxx",//固定值
  "quoteStrin1": "@name",//引用其他属性
  "user": {
    "name": "demo"
  },//固定值
  "quoteString": "@user/name",//引用其他属性
 })
{
    "date":"2020-06-29",
    "float":2202285915843574.5,
    "name":"xxxx",
    "quoteStrin1":"xxxx",
    "user ":{
       "name":"demo"
    },
    "quoteString":"demo"
}

需要注意,如果引用的属性名和 Mock 占位符名称一样(上面例子中的 quoteStrin1),引用值优先级比占位符高,所以最后 quoteStrin1 属性值与属性 name 的属性值一致,而不是占位符生成的值(Paul Miller)。

Mock 函数

1.Mock.mock

拦截请求,生成模拟数据

var data = Mock.mock("https://www.baidu.com", {
    "string|1-10": "★", //随机生成 1-10 个字符串"★"
})
var request = new XMLHttpRequest();
request.open("GET", "https://www.baidu.com", true);
request.send();
request.onreadystatechange = function () {
    if (request.readyState === 4 && request.status === 200) {
        console.log(request.responseText)
    }
}

直接生成模拟数据

var data = Mock.mock("https://www.baidu.com", {
    "string|1-10": "★", //随机生成 1-10 个字符串"★"
})
//{"string":"★★"}

2.Mock.Random

Mock.Random 是一个工具类,用于生成各种随机数据。
Mock.Random 提供的完整方法如下:

类型 方法 备注
Basic boolean, natural, integer, float, character, string, range
Date date,time, datetime, now
Image image, dataImage 生成图片地址
Color color,hex,rgb,rgba,hsl
Text paragraph, sentence, word, title, cparagraph, csentence, cword, ctitle
Name first, last, name, cfirst, clast, cname
Web url, domain,protocol, email, ip, tld
Address region,province,city,county,zip
Helper capitalize, upper, lower, pick, shuffle 方法,Mock.mock('@lower("HELLO")')->hello
Miscellaneous uuid,guid, id,increment

还可以使用 Random.extend 拓展占位符,官网示例:

Random.extend({
    constellation: function(date) {
        var constellations = ['白羊座', '金牛座', '双子座', '巨蟹座', '狮子座', '处女座', '天秤座', '天蝎座', '射手座', '摩羯座', '水瓶座', '双鱼座']
        return this.pick(constellations)
    }
})
Random.constellation()
// => "水瓶座"
Mock.mock('@CONSTELLATION')
// => "天蝎座"
Mock.mock({
    constellation: '@CONSTELLATION'
})
// => { constellation: "射手座" }

参考资料

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342