基于Flask实现的一个简易Mock平台,使用标准json结构体编写Mock Api https://github.com/yinquanwang/MockServer

 

Key Features

  • 遵循Http协议,支持GET 、POST 、PUT 、DELETE 常用http请求方式
  • mock结构体为标准json结构,支持参数内容规则制定以及对象返回信息
  • 内置常用校验器,equals、contains、between、length、type, 可灵活自己扩展
  • 支持自定义报文Valid与Invalid,返回报文可以是任意类型
  • 数据类型丰富,支持string、int、float、list、dict

得益于Flask强大的路由系统,设计核心就是将所有请求的path归一化到一个视图函数处理:

@app.route('/<path:path>', methods=['GET', 'PUT', 'DELETE', 'POST'])
def dispatch_request(path):
"""
mock view logic
:param path: request url for mock server
:return: response msg that use default or custom defined
"""
m = models.Api.query.filter_by(url=request.path, method=request.method).first_or_404()
body = json.loads(m.body)
return domain_server(**body) @app.errorhandler(404)
def url_not_found(error):
return json.dumps({
"status": 404,
"msg": "the request url not found,please check"
})

如果mock脚本不自定义返回报文,由系统默认提供,默认标准json结构体

VALID = {
"success": True,
"code": "0000",
"msg": "success"
} INVALID = {
'code': '0020',
'msg': 'request data invalid',
'success': False
} MISS = {
'code': '0021',
'msg': 'request data missed',
'success': False
} TYPE_NOT_MATCH = {
"success": False,
"code": "0001",
} EQUALS = {
"success": False,
"code": "0005",
} NOT_BETWEEN = {
"success": False,
"code": "0007",
} STR_NOT_CONTAINS = {
"success": False,
"code": "0004",
} STR_TOO_LONG = {
"success": False,
"code": "0006",
}

由此我们必须实现一个校验器,对各个字段进行一些基本校验

class Validator:
"""
Validator for mock check
""" @classmethod
def valid(cls, response=None):
return get_response(response, VALID) @classmethod
def type_not_match(cls, type, data, response=None):
msg = '{data} must be {type} type'.format(data=data, type=type)
TYPE_NOT_MATCH['msg'] = msg
if type == 'int':
if not isinstance(data, int):
return get_response(response, TYPE_NOT_MATCH)
elif type == 'float':
if not isinstance(data, float):
return get_response(response, TYPE_NOT_MATCH)
elif type == 'string':
if not isinstance(data, str):
return get_response(response, TYPE_NOT_MATCH)
elif type == 'bool':
if not isinstance(data, bool):
return get_response(response, TYPE_NOT_MATCH)
elif type == 'list':
if not isinstance(data, list):
return get_response(response, TYPE_NOT_MATCH)
elif type == 'dict':
if not isinstance(data, dict):
return get_response(response, TYPE_NOT_MATCH)
else:
return False @classmethod
def is_not_equals(cls, data, expect, response=None):
if data != expect:
msg = '{data} must be equals {expect}'.format(data=data, expect=expect)
EQUALS['msg'] = msg
return get_response(response, EQUALS)
else:
return False @classmethod
def is_not_between(cls, data, between, response=None):
try:
min = between[0]
max = between[1]
except IndexError:
return {'msg': 'mock config error'}
if data > max or min < min:
msg = '{data} must be between in {between}'.format(data=data, between=between)
NOT_BETWEEN['msg'] = msg
return get_response(response, NOT_BETWEEN)
else:
return False @classmethod
def is_not_contains(cls, data, expect, response=None):
if data not in expect:
msg = '{data} not in {expect}'.format(data=data, expect=expect)
STR_NOT_CONTAINS['msg'] = msg
return get_response(response, STR_NOT_CONTAINS)
else:
return False @classmethod
def is_too_long(cls, data, length, response=None):
if len(data) > length:
msg = '{data} is too long, max length is {length}'.format(data=data, length=length)
STR_TOO_LONG['msg'] = msg
return get_response(response, STR_TOO_LONG)
else:
return False

接下来便是对请求数据与期望数据匹配,从而返回相应报文了

def domain_server(**kwargs):
"""
used for POST PUT DELETE
:param kwargs: standard json mock scripts
:return: response msg
"""
data = kwargs.get('data', {})
invalid = kwargs.get('invalid', {}) if request.json:
form = request.json elif request.form:
form = request.form elif request.args:
form = request.args if data is {}: # do not have any parameters
return Validator.valid(response=kwargs.get('valid')) else:
if len(form) != len(data): # data do not matched
return json.dumps(MISS, ensure_ascii=False) for key in form.keys():
if key not in data.keys():
return json.dumps(INVALID, ensure_ascii=False) for key, value in form.items(): # usually validators
expect = data.get(key)
type = expect.get('type')
msg = Validator.type_not_match(type, value, response=invalid.get('type'))
if msg:
return msg contains = expect.get('contains')
if contains:
msg = Validator.is_not_contains(value, contains, response=invalid.get('contains'))
if msg:
return msg equals = expect.get('equals')
if equals:
msg = Validator.is_not_equals(value, equals, response=invalid.get('equals'))
if msg:
return msg long = expect.get('long')
if long:
msg = Validator.is_too_long(value, long, response=invalid.get('length'))
if msg:
return msg between = expect.get('between')
if between:
msg = Validator.is_not_between(value, between, response=invalid.get('between'))
if msg:
return msg return Validator.valid(response=kwargs.get('valid'))

指导说明

  1. example for get request

     

    json { "data": { "password": { "equals": "lcc", "type": "string" }, "username": { "equals": "lcc", "type": "string" } }, "invalid": { "equals": { "msg": "恭喜啊,查询到该账号了" }, "type": "类型不匹配啊" }, "method": "GET", "name": "查询接口", "url": "/get/", "valid": { "msg": "查询成功啦", "success": true } } 例如上述json结构体,此get请求有两个参数username,password, type=string,equals=lcc ,规定了valid报文和invalid中的equals报文

 

 
  1. example for post 支持json和form,系统会自动进行分辨

     

    json { "data": { "email": { "equals": { "lcc": "lcc@qq.com", "yqw": "yqw@qq.com" }, "type": "dict" }, "password": { "type": "string" }, "username": { "equals": "lcc", "length": 10, "type": "string" } }, "invalid": { "equals": { "msg": "哥们,类型不匹配啊" }, "type": "类型不匹配啊" }, "method": "POST", "name": "注册接口", "url": "/register/", "valid": { "msg": "注册成功啦" } }

  2. example for put

     

    json { "data": { "identity": { "equals": "1", "type": "string" } }, "invalid": { "equals": { "msg": "啊哦 该账号没有记录哦" }, "type": "类型不匹配啊" }, "method": "put", "name": "更新接口", "url": "/put/", "valid": { "msg": "查询成功啦", "success": true } }

  3. example for delete

     

    json { "data": { "account": { "equals": "lcc123456", "length": 10, "type": "string" } }, "invalid": { "equals": { "msg": "啊哦 该账号没有记录哦" }, "type": "类型不匹配啊" }, "method": "delete", "name": "删除接口", "url": "/del/1/", "valid": { "msg": "删除成功啦", "success": true } } ## 由于第一次接触Flask,mock的理解自己可能也有偏差,所以还请各位大神不要见怪

本地开发环境部署

  1. git clone 或者 checkout至本地目录
  2. 修改:MockServer/config.py 数据库相关配置 python USERNAME = 'root' PASSWORD = 'lcc123456' HOST = '127.0.0.1' DB = 'MockServer'
  3. 安装相应依赖库 bash pip install -r requirements.txt
  4. 创建MockServer数据库, 默认DB是MockServer
  5. 生成数据库迁移脚本,应用表结构 bash python manage.py db init python manage.py db migrate python manage.py db upgrade
  6. Start Server bash python run.py

MockServer的更多相关文章

  1. mockServer学习

    mockServer学习 很喜欢mockserver官方主页的背景颜色和格式 官方主页如下: http://www.mock-server.com/

  2. 【Mock】【接口测试】【面试】mock-server 环境搭建—加分项!

    mock-server 环境搭建 前言 mock 除了用在单元测试过程中,还有一个用途,当前端开发在开发页面的需要服务端提供 API 接口 此时服务端没开发完成,或者说没搭建测试环境,这个时候前端开发 ...

  3. 【Mock】mock-server 环境搭建

    前言 mock 除了用在单元测试过程中,还有一个用途,当前端开发在开发页面的时候,需要服务端提供 API 接口 此时服务端没开发完成,或者说没搭建测试环境,这个时候前端开发会自己 mock一个 api ...

  4. 使用mockserver来进行http接口mock

    转载自:https://blog.csdn.net/heymysweetheart/article/details/52227379:(注,这个不是很符合我的要求,它主要的作用是可以通过简单的代码就能 ...

  5. nodejs结合apiblue实现MockServer

    apiblue功能很强大,里面支持很多插件,这些插件能够为restfulAPI提供接口文档自动生成,甚至Mockserver的功能,当然,好多插件还是有很多坑的.下面用apiblue实现下面的业务需求 ...

  6. MockServer 入门

    忽略元数据末回到原数据开始处 MockServer介绍及文档 借鉴公司的文档 http://mock-server.com github:https://github.com/jamesdbloom/ ...

  7. MockServer的测试思想与实现

    转载:http://blog.csdn.net/shen1936/article/details/50298901 背景 什么是MOCK Mock的定义 Mock框架简介 Mock在单测中的应用 De ...

  8. 使用Fiddler作为简单的mockserver

    转载:  http://blog.csdn.net/xt0916020331/article/details/66544526 开发中经常遇到调试过程中对接系统接口无法联调或者后台未开发完成等情况.这 ...

  9. postman里面的mockserver使用方法

    转载:http://blog.csdn.net/Cloud_Huan/article/details/78326159 首先说下mockserver是干啥的,从英文翻译理解就是模拟一个服务器,通俗点说 ...

  10. MockServer jar包安装

    github地址: https://github.com/jamesdbloom/mockserver 1. org.apache.maven.plugin-tools:maven-plugin-an ...

随机推荐

  1. 在$CF$水题の记录

    CF1158C CF1163E update after CF1173 很好,我!expert!掉rating了!! 成为pupil指日可待== 下次要记得合理安排时间== ps.一道题都没写的\(a ...

  2. db2缓冲池

    CREATE BUFFERPOOL DEMOBP IMMEDIATE  SIZE 250 AUTOMATIC PAGESIZE 4 K ; CREATE BUFFERPOOL DEMOBP IMMED ...

  3. Sass--嵌套选择器

    Sass 中还提供了选择器嵌套功能,但这也并不意味着你在 Sass 中的嵌套是无节制的,因为你嵌套的层级越深,编译出来的 CSS 代码的选择器层级将越深,这往往是大家不愿意看到的一点.这个特性现在正被 ...

  4. vue-axios请求

    <template> <div> <div v-if="!repoUrl">loding</div> <div v-else& ...

  5. window.onload中失效的问题

    在页面中,我们有时候想让页面加载的时候有多个JS事件,一般的时候我们会这样做 window.onload=function(){ alert("aaa"); } window.on ...

  6. ajax中json格式数据如何朝后端发送数据

  7. parse_str()函数怎么用?

    php parse_str()函数 语法 parse_str()函数怎么用? php parse_str()函数表示将字符串解析成多个变量,语法是parse_str(string,array),如果未 ...

  8. PHP curl_multi_info_read函数

    curl_multi_info_read — 获取当前解析的cURL的相关传输信息 说明 array curl_multi_info_read ( resource $mh [, int &$ ...

  9. PHP chown() 函数

    定义和用法 chown() 函数改变指定文件的所有者. 如果成功则返回 TRUE,如果失败则返回 FALSE. 语法 chown(file,owner) 参数 描述 file 必需.规定要检查的文件. ...

  10. 常见sql操作

    1. select '`'||b.mrchno 商户号, b.name 商户名称, b.contact3 注册地址联系人, '`'||b.telno1 邮寄地址联系电话, a.MRCHT_NAME X ...