web开发 之 mock方案研究

本文联合作者: 诺之林 / 小怪兽 / 代码猴

目录

json-server

basic

  • GET
curl -X GET http://localhost:3000/todos

curl -X GET http://localhost:3000/todos/1
  • POST
curl -X POST -H "Content-type: application/json" -d '{"todo":"Post ToDo"}' http://localhost:3000/todos
  • PATCH
curl -X PATCH -H "Content-type: application/json" -d '{"todo":"Patch ToDo"}' http://localhost:3000/todos/1
  • DELETE
curl -X DELETE http://localhost:3000/todos/5

config

  • json-server.json
{
    "port": 3001,
    "routes": "routes.json"
}
  • routes.json
{
    "/api/*": "/$1",
    "/items\\?id=:id": "/todos/:id"
}

advanced

  • Filter
curl -X GET http://localhost:3000/posts?title=post-title-1
  • Paginate
curl -X GET http://localhost:3000/posts?_page=2
  • Sort
curl -X GET http://localhost:3000/posts?_sort=title&_order=desc
  • Slice
curl -X GET http://localhost:3000/posts?_start=2&_end=5

faker

curl -X GET http://localhost:3000/employees

小结

  • 简单

  • 快速

  • RESTful

Easy Mock

Example

  • GET
curl -X GET http://www.easy-mock.com/mock/59db1b2647bc3811aa7c4225/example/machines

curl -X GET http://www.easy-mock.com/mock/59db1b2647bc3811aa7c4225/example/machines?machine_state=on
  • POST
curl -X POST -H "Content-type: application/json" -d '{"machine_name":"挖掘机A01"}' http://www.easy-mock.com/mock/59db1b2647bc3811aa7c4225/example/machines
  • PATCH
curl -X PATCH -H "Content-type: application/json" -d '{"machine_name":"挖掘机Z01"}' http://www.easy-mock.com/mock/59db1b2647bc3811aa7c4225/example/machines/999
  • DELETE
curl -X DELETE http://www.easy-mock.com/mock/59db1b2647bc3811aa7c4225/example/machines/999

Mock.js

{
  "code": 0,
  "result": {
    'data|1-10': [{
      'id|+1': 100,
      machine_name: '@ctitle(3, 20)',
      captain_name: '机长@cname(2, 3)',
      assets_code: 'AC@integer(10000000, 99999999)',
      image_cover_url: '@image("200x200", "#00405d", "#FFF", "测试图片")',
      'is_online|1-2': true,
      source: '@pick(["bought", "rented", "unknown"])',
      machine_state: function({
        _req,
        Mock
      }) {
        if (_req.query.machine_state === 'on') {
          return 'on'
        } else if (_req.query.machine_state === 'off') {
          return 'off'
        } else {
          return Mock.mock('@pick(["on", "off"])')
        }
      },
      height: '@float(1, 100, 1, 2)',
    }],
    total_count: '@integer(1, 10)',
  }
}

小结

  • 在线服务

  • 可视化

  • 快速

dva

basic

  • .roadhogrc.mock.js
const mock = {};
require('fs').readdirSync(require('path').join(__dirname + '/src/mock')).forEach(function (file) {
  Object.assign(mock, require('./src/mock/' + file));
})
module.exports = mock;
  • ./src/mock/machine.js
const Mock = require('mockjs');

const database = Mock.mock({
  'data|20': [
    {
      'id|+1': 100,
      machine_name: '@CTITLE(3, 20)',
    },
  ],
}).data;

module.exports = {
  ['GET /machines'](req, res) {
    const pageSize = 10;
    const page = 1;

    res.status(200).json({
      data: database.slice((page - 1) * pageSize, page * pageSize),
      total: database.length,
    });
  },
}

advanced

  • .roadhogrc.mock.js
import Mock from 'mockjs';
import mockTemplate from './src/mock';

const mockApi = {};

mockTemplate.forEach((routerObject) => {
    if (routerObject.isMock === true) {
        mockApi[routerObject.method + ' /mock' + routerObject.router] = (req, res) => {
            res.end(JSON.stringify(
                Mock.mock({
                    "XCmdrCode": 0,
                    'XCmdrResult': routerObject.data,
                })
            ));
        };
    }
});

export default mockApi;
  • .roadhogrc.js
proxy: {
    "!/mock/**": {
        target: {
            host: "sa.zhgcloud.com",
            protocol: "https:",
            port: 443
        },
        ignorePath: false,
        changeOrigin: true,
        secure: false,
        bypass: function (req, res, proxyOptions) {
            if (req.path.indexOf('/mock') !== 0 && req.headers['x-cmd-request'] === undefined && req.headers['x-requested-with'] === undefined) {
                return './public/index.html';
            }
        },
    }
}
  • ./src/mock/index.js
export default [
    {
        method: 'GET',
        router: '/machines/:id',
        data: {
            'data_list|0-10': [{
                'id|+1': 1,
                machine_name: 'mock GET @CTITLE(2,20)',
            }],
        },
        isMock: true,
    }, 
];
  • ./src/utils/request.js
import fetch from 'dva/fetch';
import pathToRegexp from 'path-to-regexp';
import mockTemplate from '../mock';
import request from '../utils/request';

function isMock(method, url) {
    let hasMock = false;
    mockTemplate.forEach((routerObject) => {
        if (routerObject.isMock === true && method === routerObject.method && pathToRegexp(routerObject.router).exec(url.split('?')[0]) !== null) {
            hasMock = true;
        }
    });
    return hasMock;
}

const apiFetch = (url, options) => {
    const method = options.method !== undefined ? options.method.toUpperCase() : 'GET';

    if (isMock(method, url)) {
        return fetch(`/mock${url}`, options);
    } 
    
    return fetch(url, options);
};

小结

  • 非侵入式

  • 部分mock

  • 数据格式校验

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

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,656评论 18 139
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,103评论 4 62
  • 近日林丹令人震惊的爆出背妻偷食事件,引起不少热议,大家众说纷纭,各执其词,实在是够热闹了。看了几天,本不愿置评,但...
    西风瘦马欧阳阅读 227评论 1 2
  • 导 语 肖莉莉是别人介绍过来的美女,据说:这个女的已经失恋三个月,也是时候找个男朋友了。而刚好,我也空窗期了很久。...
    飘雨桐V阅读 347评论 0 0
  • 喜阅哲妈阅读 283评论 0 0