hc-mocker
v0.0.3
Published
Mocker是基于JSON-schema的数据模拟工具
Downloads
14
Readme
Mocker 基于JSON-schema的数据模拟工具
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)
}