0.0.3 • Published 6 years ago

hc-mocker v0.0.3

Weekly downloads
2
License
MIT
Repository
-
Last release
6 years ago

Mocker 基于JSON-schema的数据模拟工具 GitLab license

Usage

$ tnpm install hc-mocker --save-dev

API使用

在使用模拟数据之前,需要先实例化Mocky返回mocker实例

const Mocky = require('hc-mocker/mocky');
const mocker = new Mocky();
mocker.mock({data: 1}).then(function(result){
    console.log(result); // == {data: 1}
});

对于client端使用,直接实例化Mocky对象,获取mocker实例 在Server端作为express的中间件,内部已经实例化一个mocker实例,通过中间件中response.mocker可以获取到。

mocker调用接口

调用方法参数描述
mock(result, mockOption, responseType)result <Any>, mockOption <Object, null>, responseType <String, null>根据输入数据或者配置项,返回模拟数据对象
  • result是数据对象 或者 schema对象
  • mockOption, 当result需要动态处理,或者需要进一步加工处理时,通过mockOption来指定处理逻辑。
    mockOption = {
        url,             // 动态获取result的请求地址
        mock,            // 直接指定mock数据结果,直接跳过所有逻辑,以mock指定的数据对象作为最终的返回数据。
        responseType,    // 同mock函数中的responseType一样,优先级更高。
        getSchema(result)// 是一个函数,传入result作为参数,返回最终的schema对象(作为result来使用)
    }
  • responseType,在mock数据时,mocker实例会去result做一层统一的包装,返回最终的result。

    // 比如对于接口的数据返回的标准数据格式为以下结构:
    {
        rid: xxx,
        data: {...},
        status: 200
    }
    // 而我们在模拟数据时,一般只会针对data部分做mock,此时调用mock函数时,result为data部分,而模拟数据后,最终返回的数据是以上结构,这就是response包装,在Mocky静态属性会再次提到如何设定response包装逻辑。

    数据对象 vs schema对象

    • 数据对象时,一级属性不存在type,如果存在type属性会被当做schema来处理,这里需要注意一下。
    • schema对象是遵循JSON-Schema格式,schema的一级属性会有一个type,用来支持是什么类型的数据。

Mocky对象静态属性

静态属性描述
fetch获取动态result时,发起请求的实现逻辑,默认是通过window.Fetch来调用,对于
schemaContextresult为schema时,schema中声明的属性可以来自于外部schema,通过ref属性来指定,参考JSON-Schema格式, 而schemaContext是作为获取外部schema的上下文,传入ref获取指定外部schema
customFormatMock对于数据模拟时,可以定义模拟数据的逻辑,通过customFormatMock来指定
getResponse对result数据对象进行response包装,参考mock Api使用的样例。getReponse可以自定义包装的逻辑。
getSchema当result只是一个中间数据,通过指定getSchema来返回真实的result。以供mock方法处理

client端使用

  • 模拟数据
    var Mocky = require('hc-mocker/mocky');
    var mocker = new Mocky();
    // schema格式的数据
    var schema = {
        type: 'string'
    }
    // 模拟数据,返回promise
    var promise = mocker.mock(schema);
    promise.then(data => {
        console.log(data);
    });
    /**
     * 数据模拟结果 => 
     * {
     *  data: "DJ首度家居现代落地灯简约时尚落地灯饰立式台灯客厅卧室台灯",
     *  requestId: "bb037fe0-f6e2-11e7-9436-17206e25a43d"
     * }
     */
    
    // 模拟数据,返回promise,传入数据为object类型的schema
    var promise = mocker.mock({
        type: 'object',
        properties: {
            test: {
                type: 'string'
            }
        }
    });
    promise.then(data => {
        console.log(data);
    });
    /**
     * 数据模拟结果 => 
     * {
     *  data: {
     *    test: "T-2415日本泰福高"
     *  },
     *  requestId: "0d44c7f0-f6e3-11e7-9436-17206e25a43d"
     * }
     */
    
    // 模拟数据,返回promise,如果不是schema结构的数据,则直接返回
    var promise = mocker.mock({test: 1});
    promise.then(data => {
        console.log(data);
    });
    /**
     * 数据模拟结果 => 
     * {
     *  test: 1
     * }
     */

掌握JSON-schema, 参考地址

    {
        "title": "Person",
        "type": "object",
        "properties": {
            "firstName": {
                "type": "string"
            },
            "lastName": {
                "type": "string"
            },
            "age": {
                "description": "Age in years",
                "type": "integer",
                "minimum": 0
            }
        },
        "required": ["firstName", "lastName"]
    }

在项目中使用

  • → 在请求接口之前,替换为mock逻辑
    const $ = require('jquery');
    // 准备好一份接口映射的数据结构
    const proxyMap = {
        'GET /api/getUser': {
            url: './devtool/schemas/user.json'
        }
    }
    function request(ajaxOption){
        // 在debug=true时,做模拟数据
        if(window.location.indexOf('debug=true') > -1) {
            // 通过动态
            const path = ajaxOption.method + ' ' + ajaxOption.url.split('?')[0]; // == `GET /api/getUser`
            return mocker.mock(null, proxyMap[path]);
        }else{
            return $.ajax(ajaxOption)
        }
    }
    request({
        url: '/api/getUser',
        method: 'GET'
    });
  • → 在请求接口过程中拦截
    var mockData = require('./devtool/schemas/user.json');
    // 提前注册url对应的模拟数据进去
    mocker.mock('/api/getUser', mockData);

    // 发请求时,会自动替换为模拟数据
    $.ajax({
        url: '/api/getUser'
    });

只能拦截浏览器XHR请求,不能拦截Fetch

server端使用

中间件配置项

属性名描述
file接口代理的配置文件
routes接口代理的路由配置
path当路由拦截成功,真实的数据文件path.join(path, app.config.prefix, req.path + '.json')

作为honeybee中间件

mocker: {
    enable: true,
    module: 'hc-mocker',
    config: {
        file: './assets/devtool/proxyMap.js',
        routes: [
            {
                test: /\/api/demo/*/
            },
            {
                test: '/api/setting',
                responseType: 'object'
            },
            '/api/*'],
        path: './assets/devtool'
    }
}
  • assets/devtool/proxyMap.js文件
module.expors = {
    '/api/getUser': {
        url: '/devtool/schemas/user.json'
    }
}
  • → client请求接口为/api/getUser
  • 优先从file配置文件proxyMap.js中匹配,并且找到/api/getUser对应的代理配置项。
  • 返回的数据会为/devtool/schemas/user.json
  • 如果json文件格式为JSON-schema,则会根据再进一步mock数据返回。
  • → client接口请求为/api/test
  • proxyMap.js文件中找不到映射的配置,但是匹配拦截的路由/api/*
  • hc-mocker中间件会抓取/assets/devtool/api/test.json文件内容转为JSON返回
  • 如果数据格式为JSON-schema,则会根据再进一步mock数据返回。

注意/assets/devtool/为中间件配置的path属性

  • → 代理配置项的理解
    var proxy = {
        // 接口路由匹配条件,test为字符串时会转为正则保存
        test: `String | RegExp`,
        // 匹配成功后,从url获取数据返回,如果识别是schema会基于schema做模拟数据返回
        url: `String`,
        // 如果存在mock,则直接当做数据返回
        mock: `Object`,
        // 当要处理schema时,根据responseType,调用内置模板,包装schema对象
        responseType: [object|array|list|boolean|integer|string|null|undefined|exception],
        // 自定义schema对象来进行数据模拟
        getSchema: `Function`
    }

内置的responseType模板

    // responseType = 'array'
    {
        type: 'array',
        items: schema
    }
    // responseType = 'object'
    {
        type: 'object',
        properties: schema.properties
    }
    // responseType = 'list'
    {
        type: 'object',
        properties: {
            data: {
                type: 'array',
                items: schema
            },
            total: {
                type: 'integer'
            }
        }
    }
    // responseType = 'exception':
    {
        errorCode: {
            type: 'integer'
        },
        errorMessage: {
            type: 'string'
        }
    }
    // responseType = 'undefined':
    undefined
    // responseType = 'null':
    null
    // responseType = 'string' | 'boolean' | 'integer'
    schema

内置responseType模板处理是通过Mocky.getResponse方法来实现,覆盖Mocky.getResponse方法达到自定义效果。

包装schema

在代理配置项中,可以通过设置getSchema方法来包装schema,否则会基于Mocky.getSchema包装。

Mocky.getSchema包装逻辑:

    // schema.type有type属性时
    {
        type: 'object',
        properties: {
            requestId: {
                type: 'string',
                format: 'uuid'
            },
            data: schema
        }
    } 
    // 否则
    {
        type: 'object',
        properties: Object.assign({
          requestId: {
            type: 'string',
            format: 'uuid'
          }
        }, schema)
    }