有时候我们开发一般会分为前后端,前端负责数据显示和UI交互,后端负责数据IO等等。因此造成前端对后端有严重依赖,使得前端的开发进度普遍滞后于后端。

为了使得前端减轻对后端的依赖,在后端功能尚未实现的情况下保证前端进度的开发,我们一般会手动进行一些数据模拟,即假数据。然而编写这些假数据又是一个及其消耗时间、精力的工作;在测试中,由于假数据是手工编写的,测试用例覆盖率低,难以真正进行有效测试。

Mock

以上问题的痛点是:

  1. 前端依赖后端,工作难以开展
  2. 假数据编写工作量大、覆盖率低

针对以上痛点,Mock的需求和解决方案是:

  1. 不依赖后端:模拟后端,接受前端请求
  2. 自动生成假数据:数据类型多样、覆盖率高
  3. 系统耦合:低耦合,当后端真正上线,可以立即替换

引用Mock.js文档的一段话:

Mock.js 是一款模拟数据生成器,旨在帮助前端攻城师独立于后端进行开发,帮助编写单元测试。提供了以下模拟功能:

  1. 根据数据模板生成模拟数据
  2. 模拟 Ajax 请求,生成并返回模拟数据
  3. 基于 HTML 模板生成模拟数据

具体使用

Mock这种想法在大部分语言都有具体实现的工具包,此处只介绍JavaScript上的使用。一下例子大部分是从Mock.js中来,请查看具体文档。

HTML中:<script src="http://mockjs.com/dist/mock.j...;></script>
Node.js中:npm install mockjs

假数据

// 使用 Mock,根据数据模板生成模拟数据。
var data = Mock.mock({
    'list|1-10': [{
        'id|+1': 1
    }]
});
$('<pre>').text(JSON.stringify(data, null, 4))
    .appendTo('body')

结果

{
"list": [
    {
        "id": 1
    },
    {
        "id": 2
    },
    {
        "id": 3
    }
    ]
}

Mock.js 的语法规范(可参考使用Mock.js进行独立于后端的前端开发,我觉得他总结的挺好的)包括两部分:

数据模板定义(Data Temaplte Definition,DTD)
数据占位符定义(Data Placeholder Definition,DPD)

数据模板定义参数的含义和默认值如下所示:
数据模板中的每个属性由 3 部分构成,以 'data|1-10':[{}] 为例:

  1. 属性名:例如 data。
  2. 参数:指示生成数据的规则。例如 |1-10,指示生成的数组中含有 1 至 10 个元素。
  3. 属性值:表示初始值、占位符、类型。例如 [{}],表示属性值一个数组,数组中的元素是 {}。属性值中含有占位符时,将被替换为对应的随机数据,例如 'email': '@EMAIL','@EMAIL'将被替换为随机生成的邮件地址。

参数和属性值部分的语法规范和示例如下所示:

'data|1-10':[{}] 构造一个数组,含有 1-10 个元素
'data|1':[item, item, item] 从数组中随机挑选一个元素做为属性值
'id|+1': 1 属性 id 值自动加一,初始值为 1
'grade|1-100': 1 生成一个 1-100 之间的整数
'float|1-10.1-10': 1 生成一个浮点数,整数部分的范围是 1-10,保留小数点后 1-10 位小数
'star|1-10': '★' 生成一个字符串,重复 1-10 次 '★'
'repeat|10': 'A' 生成一个字符串,重复 10 次 'A'
'published|1': false 随机生成一个布尔值
'email': '@EMAIL' 随即生成一个 Email
'date': '@DATE' 随即生成一段日期字符串,默认格式为 yyyy-MM-dd
'time': '@TIME' 随机生成一段时间字符串,默认格式为 HH:mm:ss
'datetime': '@DATETIME' 随机生成一段时间字符串,默认格式为 yyyy-MM-dd HH:mm:ss

处理请求

Mock.mock( rurl?, rtype?, template|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 选项集。

Mock.mockjax(library)

覆盖(拦截) Ajax 请求,目前内置支持 jQuery、Zepto、KISSY。
对 jQuery Ajax 请求的拦截和响应,通过覆盖前置过滤器、选项 dataFilter 以及数据转换器实现,实现代码请问这里。

对 KISSY Ajax 请求的拦截和响应,则通过粗鲁地覆盖 KISSY.io(options) 实现,实现代码请问这里。

因为第三库 Ajax 的实现方式不尽相同,故目前只内置支持了实际开发中(本人和所服务的阿里) 常用的 jQuery 、Zepto KISSY。如果需要拦截其他第三方库的 Ajax 请求,可参考对 jQuery 、Zepto、 KISSY 的实现,覆盖 Mock.mockjax(library)。

例子

// Mock.mock(rurl, template)
Mock.mock(/\.json/, {
    'list|1-10': [{
            'id|+1': 1,
            'email': '@EMAIL'
        }
    ]
})
$.ajax({
    url: 'data.json',
    dataType: 'json'
}).done(function(data, status, jqXHR){
    $('<pre>').text(JSON.stringify(data, null, 4))
        .appendTo('body')
})

参考资料

github文档
Mock.js
使用Mock.js进行独立于后端的前端开发


曾纪文
201 声望22 粉丝