基于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. python基础--二分查找

    # 二分查找 def sort_search(lst,key): """ 二分查找 :param lst: 有序数列 :param key: 要查找的关键值 :retur ...

  2. C#简单的文件依赖缓存的使用

    一,FileCache.aspx页面 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind=& ...

  3. Python3学习笔记——类

    #!/usr/bin/env python #-*- coding:utf-8 -*- #面向对象(类+对象) 三大特性:封装.继承.多态 类的成员: 字段: 普通字段:保存在对象(实例)中,执行只能 ...

  4. constructor prototype __proto__

    什么是对象 若干属性的集合 什么是原型? 原型是一个对象,其他对象可以通过它实现继承. 哪些对象有原型? 所有的对象在默认情况下都有一个原型,因为原型本身也是对象,所以每个原型自身又有一个原型(只有一 ...

  5. 2019-11-7-WPF-How-to-get-plain-text-from-RichTextBox

    title author date CreateTime categories WPF How to get plain text from RichTextBox lindexi 2019-11-0 ...

  6. 三、Json方式函数

    一.Json方式函数 // 4. 查看对象信息 console.dir(obj) =>可以显示一个对象所有的属性和方法. var info = { blog: "http://cllg ...

  7. 图形设计 X11

    显示适配器驱动程序安装范例 AMD驱动加载 Intel驱动加载

  8. (PASS)JAVA数组去重 三种方法 (不用集合)

    第一种方法(只学到数组的看): 定义一个新的数组长度和旧数组的长度一样,存储除去重复数据的旧数组的数据和0, package demo01; import java.sql.Array; import ...

  9. js console对象

    js调试 根据信息的不同性质,console对象显示信息的方法,分别是一般信息console.log(),console.info().除错信息console.debug().警告提示console. ...

  10. Springmvc中的一些问题解决

    Spring mvc中的异常 做统一处理,全局异常处理器 异常处理类代码: 必须实现接口  然后返回值是ModelAndView  那就可以做个展示页面了 package com.toov5.mvc. ...