前端开发工具集(八):Mock工具(mockjs)

1,893 阅读4分钟

本文会讲mock工具,一般用于前后端分离开发时,当接口未提供时前端进行模拟接口数据,也可用于自动化测试。
主要内容是从源码出发对mockjs的几个api有更深入的了解。

前端开发工具集系列其他部分在这里


1 概述

mockjs主要有两个feature

  • 根据传入的模板返回数据
  • 拦截ajax请求并返回模板对应的数据

这个库很简单,入口文件对外暴露一个Mock对象

var Mock = {
    Handler: Handler,//用来处理数据模板
    Random: Random,//用于生成各种随机数
    Util: Util,//通用方法
    XHR: XHR,//mockjs重写的xhr对象,当匹配成功后,实际的ajax请求会走其中的逻辑
    RE: RE,//正则
    toJSONSchema: toJSONSchema,//把 Mock.js 风格的数据模板转换成 JSON Schema
    valid: valid,//校验真实数据 data 是否与数据模板 template 匹配
    heredoc: Util.heredoc,//可以用于书写多行模板
    setup: function(settings) {
        return XHR.setup(settings)
    },//对自定义xhr对象进行配置
    _mocked: {},//用于保存调用mock方法时参数的对象
    version,//版本号
    mock:function(rurl, rtype, template) {
    // Mock.mock(template)
    //当只有一个参数时会被认为是模板
    if (arguments.length === 1) {
        return Handler.gen(rurl)
    }
    // Mock.mock(rurl, template)
    //当有两个参数时,会认为http方法为undefined
    if (arguments.length === 2) {
        template = rtype
        rtype = undefined
    }
    // 拦截 XHR
    if (XHR) window.XMLHttpRequest = XHR
    Mock._mocked[rurl + (rtype || '')] = {
        rurl: rurl,
        rtype: rtype,
        template: template
    }
    return Mock
}
}

2 使用

对于这个库我们主要关注一个api一个语法

2.1 api

这个api就是Mock.mock,就像上面说的,可以传递一到三个参数

Mock.mock( rurl?, rtype?, template|function( options ) )
  • 当一个时表示返回一个符合指定模板的数据或者执行指定回调
  • 当两个时表示拦截指定路径的ajax请求,并结合另一个参数返回数据
  • 当三个时在两个的基础上添加了请求方法的匹配项

其中一个参数时实际上调用的是Handler.gen(rurl),后者在这里定义,这里的参数是模板template,会对template进行解析,其他情况会在解析之前匹配对应路径和方法,具体解析过程见下一节。

2.2 语法

这个语法就是前文的template参数,分为数据模板和数据占位符两种。
模板的解析在Handler中处理。

2.2.1 数据模板

数据模板由三部分组成

// 属性名   name
// 生成规则 rule,可选,包括min-max、count、min-maxmin-max.dcount、count.dmin-dmax、count.dcount、+step
// 属性值   value
'name|rule': value

生成规则的具体含义根据属性值的类型进一步确定,计算类型方法为

function type(obj) {
    return (obj === null || obj === undefined) ? String(obj) : Object.prototype.toString.call(obj).match(/\[object (\w+)\]/)[1].toLowerCase()
}

其中属性值中可以包含下一节介绍的占位符。
属性值用来指定返回值的类型和初始值

根据属性值的类型可分为以下情况

  • string
    • min-max 表示重复次数的范围
    • count 重复的次数
  • number
    • +step 当同时输出多组时后一个比前一个加step
    Mock.mock({
    'list|1-10': [{
        'id|+1': 1,
    	}],
    }
    
    • min-max 范围
    • min-max.dmin-dmax min到max的范围,小数点在dmin和dmax之间
    • count.dcount
  • boolean
    • count 表示当前属性值是相反属性值的概率倍数,比如0就是当前值出现概率为0
    • min-max 当前值与相反值得概率比例
  • object
    • count 从属性值中随机选取count个属性
    • min-max
  • array
    • count 当为1时选取数组中一项,其他时表示重复数组中元素的次数
    • +step 选取数组中第一个元素
    • min-max 重复属性值次数
  • function 执行该对象的返回值
  • regexp 反向生成匹配的字符串,这部分源码在这里,有兴趣可以看一下

2.2.2 数据占位符

占位符是指以@开头的字符串,格式为

@占位符
@占位符(参数 [, 参数])

占位符引用的是Mock.Random中的方法,相当于调用对应方法。

还可以通过Random.extend扩展,比如

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

源码在这里,文档在这里


完结撒花