MockServer
基于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'))
指导说明
- 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报文


- 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": "注册成功啦" } }
- example for put
json { "data": { "identity": { "equals": "1", "type": "string" } }, "invalid": { "equals": { "msg": "啊哦 该账号没有记录哦" }, "type": "类型不匹配啊" }, "method": "put", "name": "更新接口", "url": "/put/", "valid": { "msg": "查询成功啦", "success": true } }
- 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的理解自己可能也有偏差,所以还请各位大神不要见怪
本地开发环境部署
- git clone 或者 checkout至本地目录
- 修改:MockServer/config.py 数据库相关配置
python USERNAME = 'root' PASSWORD = 'lcc123456' HOST = '127.0.0.1' DB = 'MockServer'
- 安装相应依赖库
bash pip install -r requirements.txt
- 创建MockServer数据库, 默认DB是MockServer
- 生成数据库迁移脚本,应用表结构
bash python manage.py db init python manage.py db migrate python manage.py db upgrade
- Start Server
bash python run.py
MockServer的更多相关文章
- mockServer学习
mockServer学习 很喜欢mockserver官方主页的背景颜色和格式 官方主页如下: http://www.mock-server.com/
- 【Mock】【接口测试】【面试】mock-server 环境搭建—加分项!
mock-server 环境搭建 前言 mock 除了用在单元测试过程中,还有一个用途,当前端开发在开发页面的需要服务端提供 API 接口 此时服务端没开发完成,或者说没搭建测试环境,这个时候前端开发 ...
- 【Mock】mock-server 环境搭建
前言 mock 除了用在单元测试过程中,还有一个用途,当前端开发在开发页面的时候,需要服务端提供 API 接口 此时服务端没开发完成,或者说没搭建测试环境,这个时候前端开发会自己 mock一个 api ...
- 使用mockserver来进行http接口mock
转载自:https://blog.csdn.net/heymysweetheart/article/details/52227379:(注,这个不是很符合我的要求,它主要的作用是可以通过简单的代码就能 ...
- nodejs结合apiblue实现MockServer
apiblue功能很强大,里面支持很多插件,这些插件能够为restfulAPI提供接口文档自动生成,甚至Mockserver的功能,当然,好多插件还是有很多坑的.下面用apiblue实现下面的业务需求 ...
- MockServer 入门
忽略元数据末回到原数据开始处 MockServer介绍及文档 借鉴公司的文档 http://mock-server.com github:https://github.com/jamesdbloom/ ...
- MockServer的测试思想与实现
转载:http://blog.csdn.net/shen1936/article/details/50298901 背景 什么是MOCK Mock的定义 Mock框架简介 Mock在单测中的应用 De ...
- 使用Fiddler作为简单的mockserver
转载: http://blog.csdn.net/xt0916020331/article/details/66544526 开发中经常遇到调试过程中对接系统接口无法联调或者后台未开发完成等情况.这 ...
- postman里面的mockserver使用方法
转载:http://blog.csdn.net/Cloud_Huan/article/details/78326159 首先说下mockserver是干啥的,从英文翻译理解就是模拟一个服务器,通俗点说 ...
- MockServer jar包安装
github地址: https://github.com/jamesdbloom/mockserver 1. org.apache.maven.plugin-tools:maven-plugin-an ...
随机推荐
- docker--shell和Exec格式
shell格式 RUN apt-get install -y vim CMD echo "docker so easy" ENTRYPOINT echo "docker ...
- js自增++与自减--运算符
/** * 自增(++)与自减(--)运算符 */ // 自增示例 var a = 1, c, d, e; console.log(`a++ = ${a++}`); // a++ = 1 consol ...
- DVR和NVR的区别(深度好文)(转)
DVR接模拟摄像机,NVR是接IP camera的录像机. DVR的录像效果取决于摄像机与DVR本身的压缩算法与芯片处理能力,而NVR的录像效果则主要取决于IPcamera,因为IPcamera输出的 ...
- 【leetcode】942. DI String Match
题目如下: Given a string S that only contains "I" (increase) or "D" (decrease), let ...
- c# 定义operator运算符
public void TestFunc() { Complex complex1 = new Complex(); Complex complex2 = new Complex(); var s = ...
- MariaDB 安装
MariaDB的所有下载都位于官方MariaDB基金会网站的下载部分. 单击所需版本的链接,并显示多个操作系统,体系结构和安装文件类型的下载列表. 在LINUX / UNIX上安装 如果你熟悉Linu ...
- 在树莓派3B上搭建LAMP
一.安装apache2 sudo apt-get install apache2 在电脑上输入树莓派的网址会有如下显示 二.安装Mysql sudo apt-get install mysql-ser ...
- mysql学习-join的使用
sql的执行顺序是从from 开始 join图
- OC学习篇之---类目的概念和使用
上一篇文章介绍了OC中的@class关键字的使用http://blog.csdn.net/jiangwei0910410003/article/details/41774747,这一篇我们介绍一下,O ...
- vue2.0 组件的生命周期
vue官方文档中给出的vue生命周期的流程图 如下: 生命周期探究 对于执行顺序和什么时候执行,看上面两个图基本有个了解了.下面我们将结合代码去看看钩子函数的执行. <!DOCTYPE html ...