# ProxyMocker
**Repository Path**: rdtest/ProxyMocker
## Basic Information
- **Project Name**: ProxyMocker
- **Description**: 搭设mock服务,在不影响正常使用的情况下,按需拦截模拟
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 1
- **Created**: 2022-02-25
- **Last Updated**: 2022-06-10
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# proxyMocker
中转mocker服务
## 流程设计
* mocker 前,流程如下:

* mocker 后,流程如下:


## mocker 过滤过程

* 场景一:ip 不匹配,直接拦截请求,返回错误码
* 场景二:ip匹配-》api匹配-》参数匹配代码==True-》使用mock_pycode 运行结果响应
* 场景三:ip匹配-》(api不匹配 OR 参数匹配代码==False)-》转发到target_host,获取目标服务响应
## 解决测试中的问题
1. 模拟第三方服务的各种响应情况(正确场景,错误场景,超时等)
2. 通过web后台,灵活配置过滤py代码,响应py代码
## 使用实例
> 测试场景说明: 使用标普(第三方)出佣给个人的银行凭证来与内部结算中心的出佣申请进行对账。但是标普测试环境没有凭证。
#### 测试内容:
1.定时任务一:从结算中心(内部)定时检查已出佣,未获得凭证的单据-》然后调用钱包服务(内部)接口-》钱包服务调用标普接口获得银行回单—》结算中心更新出佣申请记录表中的receipt_url 字段,并保存pdf,插入附件记录表。
2.定时任务二:从结算中心(内部)定时检查已出佣,已获得凭证未校验的单据-》结算中心将银行凭证发送到RPA(AI识别,解析PDF中的单据金额等)获得凭证数据-》将凭证数据与平台出佣记录对比,对比后更新对比结果字段。
问题:标普测试环境,没有银行回单!!!
#### 测试方法
1. 使用mock方法,将钱包调标普获得银行回单接口,改成钱包调mock服务(要指定请求参数来过滤,不能所有请求都mock),模拟返回银行回单URL
2. 修改银行回单pdf内容,一来验证RPA解析是否正确,二来应对凭证校验通过与不通过的情况。
#### proxyMocker 部署(根据自己情况,仅供参考)
##### 配置nginx `xxx.xxx.xxx.net.conf`
```
server {
listen 80;
server_name xxx.xxx.xxx.net;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8002;
}
# 非必须,本次测试中需要用到在线pdf,因此配置提供在线pdf预览下载
location ^~ /download {
alias /home/guanfuchang/;
autoindex on;
autoindex_exact_size on;
autoindex_localtime on;
charset utf-8;
if ($request_filename ~* ^.*?\.(txt|doc|pdf|rar|gz|zip|docx|exe|xlsx|ppt|pptx)$){
add_header Content-Disposition: 'p_w_upload;';
}
}
}
```
##### 部署启动proxyMocker服务
```
docker-compose up -d
```
##### 修改相关配置
* 让开发修改钱包服务调标普的域名,修改为:
`xxx.xxx.xxx.net`
* 登录管理后台xxx.xxx.xxx.net/admin,修改过滤条件
>标普接口格式参考如下:
>[标普云] 发送请求 {"merCode":"xxx","reqData":{"taskNum":"RW162202421619283567"},"sign":"xxx","serviceName":"taskTradeReceiptInq","timestamp":1624957210673}
>[标普云] 接收响应 {"rspCode":"0000","rspMsg":"success","rspData":{"result":{"taskNum":"RW162202421619283567","tradeReceiptUrl":null},"code":"200","message":"操作成功"},"sign":"xxx","timestamp":"xxx"}

```python
# _*_ coding:utf-8 _*_
def param_filter(querystring,params):
# 根据需要,可以使用querystring和params参数,进行过滤,返回Trur or False,决定是否需要使用mock
# querystring 格式为字符串,eg.name="Milton"&age=18
# params 格式(一般)为字典,eg.{"name":"Milton","age":18}
# Create your filter code here,return True or False
taskNum=params.get('reqData').get('taskNum')
serviceName=params.get('serviceName')
if taskNum=="RW161821364992319617781" and serviceName=="taskTradeReceiptInq":return True
return False
```
```python
# _*_ coding:utf-8 _*_
import json
def mock_resp(querystring,params):
# 根据需要,可以获得querystring和params参数,进行逻辑处理,生成mocke响应内容
# querystring 格式为字符串,eg.name="Milton"&age=18
# params 格式(一般)为字典,eg.{"name":"Milton","age":18}
# Create your mock code here
return json.dumps({"rspCode":"0000","rspMsg":"success","rspData":{"result":{"taskNum":"RW161821364992319617781","tradeReceiptUrl":"http://pmocker.test.thinkinpower.net/download/1000.pdf"},"code":"200","message":"操作成功"},"sign":"6F8F78D771AB3AF1A5E5D6B34FE2B804","timestamp":"1624957192611"},ensure_ascii=False)
```
* 查看日志
```
接收到新请求----------------------------------------------------------------------》
2021-06-30 14:17:36.858 | DEBUG | mockerAPP.views:home:23 - 客户端请求参数处理结果:
{
"api": "/api/csp/v1",
"host": "xxx.xxx.xxx.net",
"method": "POST",
"meta": {},
"querystring": "",
"full_path": "/api/csp/v1",
"content_type": "application/json",
"headers": {
"X_REAL_IP": "10.29.253.140",
"X_FORWARDED_FOR": "120.79.181.239, 10.29.253.140",
"CONNECTION": "close",
"ACCEPT": "application/json",
"ACCEPT_CHARSET": "",
"USER_AGENT": "Java/1.8.0_191",
"Content-Type": "application/json"
},
"body": "{\"merCode\":\"abb33ccfeccj44gg\",\"reqData\":{\"taskNum\":\"RW161821364992319617781\"},\"sign\":\"57283A3437AA492157D62CC4E5B83093\",\"serviceName\":\"taskTradeReceiptInq\",\"timestamp\":1625040634780}",
"ip": "120.79.181.239, 10.29.253.140"
}
2021-06-30 14:17:36.876 | INFO | mockerAPP.views:mock_filter:108 - ip=120.79.181.239, 10.29.253.140 匹配fish记录条目:2
2021-06-30 14:17:36.879 | INFO | mockerAPP.views:mock_filter:108 - ip=120.79.181.239, 10.29.253.140 匹配fish记录条目:2
2021-06-30 14:17:36.892 | INFO | mockerAPP.views:mock_filter:115 - api_path=/api/csp/v1 匹配fish记录条目:1
2021-06-30 14:17:36.893 | INFO | mockerAPP.views:mock_filter:129 - type(querystring):,querystring:将传入到 precode 中进行处理
2021-06-30 14:17:36.894 | INFO | mockerAPP.views:mock_filter:130 - type(params):,params:{'merCode': 'abb33ccfeccj44gg', 'reqData': {'taskNum': 'RW161821364992319617781'}, 'sign': 'C84862FD5231327F3CDA6165580154DA', 'serviceName': 'taskTradeReceiptInq', 'timestamp': 1625033856846}将传入到 precode 中进行处理
2021-06-30 14:17:36.894 | INFO | mockerAPP.views:mock_filter:137 - pre_pycode 执行结果:True
2021-06-30 14:17:36.895 | WARNING | mockerAPP.views:mock_filter:140 - mocker处理--------------------------------------------------》
2021-06-30 14:17:36.922 | INFO | mockerAPP.views:mock_filter:148 - mock_pycode 执行结果:{"rspCode": "0000", "rspMsg": "success", "rspData": {"result": {"taskNum": "RW161821364992319617781", "tradeReceiptUrl": "http://pmocker.test.thinkinpower.net/download/1000.pdf"}, "code": "200", "message": "操作成功"}, "sign": "6F8F78D771AB3AF1A5E5D6B34FE2B804", "timestamp": "1624957192611"}
2021-06-30 14:17:36.923 | INFO | mockerAPP.views:mock_filter:115 - api_path=/api/csp/v1 匹配fish记录条目:1
2021-06-30 14:17:36.923 | INFO | mockerAPP.views:home:31 - mock 响应格式:
2021-06-30 14:17:36.925 | INFO | mockerAPP.views:home:19 -
```