npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

hc-mocker

v0.0.3

Published

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

Downloads

19

Readme

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来调用,对于 | | schemaContext | result为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)
    }