573 lines
15 KiB
Markdown
573 lines
15 KiB
Markdown
|
|
# 流水分析 Mock 服务器设计方案
|
|||
|
|
|
|||
|
|
**创建日期**: 2026-03-02
|
|||
|
|
**作者**: Claude Code
|
|||
|
|
|
|||
|
|
## 项目概述
|
|||
|
|
|
|||
|
|
### 背景
|
|||
|
|
当前项目需要与流水分析平台进行接口对接,但在开发和测试过程中,依赖外部真实服务存在以下问题:
|
|||
|
|
- 网络连接不稳定,影响测试效率
|
|||
|
|
- 无法控制返回数据,难以测试各种场景
|
|||
|
|
- 无法模拟错误场景和边界情况
|
|||
|
|
- 团队成员无法共享测试环境
|
|||
|
|
|
|||
|
|
### 解决方案
|
|||
|
|
开发一个独立的 Mock 服务器,基于 Python + FastAPI 技术栈,模拟流水分析平台的 7 个核心接口,支持:
|
|||
|
|
- 配置文件驱动的响应数据
|
|||
|
|
- 文件上传解析延迟模拟
|
|||
|
|
- 错误场景触发机制
|
|||
|
|
- 自动生成的 API 文档
|
|||
|
|
|
|||
|
|
### 技术选型
|
|||
|
|
|
|||
|
|
| 技术组件 | 选择 | 理由 |
|
|||
|
|
|---------|------|------|
|
|||
|
|
| Web框架 | FastAPI | 现代异步框架,自动生成API文档,强类型支持 |
|
|||
|
|
| 数据验证 | Pydantic | 与FastAPI原生集成,类型提示清晰 |
|
|||
|
|
| 配置管理 | JSON文件 | 易于修改,非开发人员也能调整测试数据 |
|
|||
|
|
| 状态存储 | 内存字典 | 轻量级,重启清空,适合Mock场景 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 整体架构
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
lsfx-mock-server/
|
|||
|
|
├── main.py # 应用入口
|
|||
|
|
├── config/
|
|||
|
|
│ ├── settings.py # 全局配置
|
|||
|
|
│ └── responses/ # 响应模板配置文件
|
|||
|
|
│ ├── token.json
|
|||
|
|
│ ├── upload.json
|
|||
|
|
│ ├── parse_status.json
|
|||
|
|
│ └── bank_statement.json
|
|||
|
|
├── models/
|
|||
|
|
│ ├── request.py # 请求模型(Pydantic)
|
|||
|
|
│ └── response.py # 响应模型(Pydantic)
|
|||
|
|
├── services/
|
|||
|
|
│ ├── token_service.py # Token管理
|
|||
|
|
│ ├── file_service.py # 文件上传和解析模拟
|
|||
|
|
│ └── statement_service.py # 流水数据管理
|
|||
|
|
├── routers/
|
|||
|
|
│ └── api.py # 所有API路由
|
|||
|
|
├── utils/
|
|||
|
|
│ ├── response_builder.py # 响应构建器
|
|||
|
|
│ └── error_simulator.py # 错误场景模拟
|
|||
|
|
└── requirements.txt
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 核心设计思想
|
|||
|
|
1. **配置驱动** - 所有响应数据在JSON配置文件中,方便修改
|
|||
|
|
2. **内存状态管理** - 使用全局字典存储运行时状态(tokens、文件记录等)
|
|||
|
|
3. **异步任务** - 使用FastAPI后台任务模拟文件解析延迟
|
|||
|
|
4. **错误标记识别** - 检测请求参数中的特殊标记触发错误响应
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 数据模型设计
|
|||
|
|
|
|||
|
|
### 请求模型
|
|||
|
|
|
|||
|
|
对应Java项目中的DTO类:
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# models/request.py
|
|||
|
|
from pydantic import BaseModel
|
|||
|
|
from typing import Optional
|
|||
|
|
|
|||
|
|
class GetTokenRequest(BaseModel):
|
|||
|
|
projectNo: str
|
|||
|
|
entityName: str
|
|||
|
|
userId: str
|
|||
|
|
userName: str
|
|||
|
|
orgCode: str
|
|||
|
|
entityId: Optional[str] = None
|
|||
|
|
xdRelatedPersons: Optional[str] = None
|
|||
|
|
jzDataDateId: Optional[str] = "0"
|
|||
|
|
innerBSStartDateId: Optional[str] = "0"
|
|||
|
|
innerBSEndDateId: Optional[str] = "0"
|
|||
|
|
analysisType: Optional[int] = -1
|
|||
|
|
departmentCode: Optional[str] = None
|
|||
|
|
|
|||
|
|
class UploadFileRequest(BaseModel):
|
|||
|
|
groupId: int
|
|||
|
|
|
|||
|
|
class FetchInnerFlowRequest(BaseModel):
|
|||
|
|
groupId: int
|
|||
|
|
customerNo: str
|
|||
|
|
dataChannelCode: str
|
|||
|
|
requestDateId: int
|
|||
|
|
dataStartDateId: int
|
|||
|
|
dataEndDateId: int
|
|||
|
|
uploadUserId: int
|
|||
|
|
|
|||
|
|
class CheckParseStatusRequest(BaseModel):
|
|||
|
|
groupId: int
|
|||
|
|
inprogressList: str
|
|||
|
|
|
|||
|
|
class GetBankStatementRequest(BaseModel):
|
|||
|
|
groupId: int
|
|||
|
|
logId: int
|
|||
|
|
pageNow: int
|
|||
|
|
pageSize: int
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 响应模型
|
|||
|
|
|
|||
|
|
对应Java项目中的VO类:
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# models/response.py
|
|||
|
|
from pydantic import BaseModel
|
|||
|
|
from typing import Optional, List, Dict, Any
|
|||
|
|
|
|||
|
|
class TokenData(BaseModel):
|
|||
|
|
token: str
|
|||
|
|
projectId: int
|
|||
|
|
projectNo: str
|
|||
|
|
entityName: str
|
|||
|
|
analysisType: int
|
|||
|
|
|
|||
|
|
class GetTokenResponse(BaseModel):
|
|||
|
|
code: str = "200"
|
|||
|
|
data: Optional[TokenData] = None
|
|||
|
|
message: str = "create.token.success"
|
|||
|
|
status: str = "200"
|
|||
|
|
successResponse: bool = True
|
|||
|
|
|
|||
|
|
# 其他响应模型类似...
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 核心业务逻辑
|
|||
|
|
|
|||
|
|
### 文件解析延迟模拟
|
|||
|
|
|
|||
|
|
**实现机制:**
|
|||
|
|
1. 上传接口立即返回,状态为"解析中"
|
|||
|
|
2. 使用FastAPI的BackgroundTasks在后台延迟执行
|
|||
|
|
3. 延迟3-5秒后更新状态为"解析完成"
|
|||
|
|
4. 轮询检查接口返回当前解析状态
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# services/file_service.py
|
|||
|
|
class FileService:
|
|||
|
|
def __init__(self):
|
|||
|
|
self.file_records: Dict[int, Dict] = {}
|
|||
|
|
self.parsing_status: Dict[int, bool] = {}
|
|||
|
|
|
|||
|
|
async def upload_file(self, group_id: int, file, background_tasks: BackgroundTasks):
|
|||
|
|
log_id = generate_log_id()
|
|||
|
|
|
|||
|
|
# 立即存储记录,标记为解析中
|
|||
|
|
self.file_records[log_id] = {
|
|||
|
|
"logId": log_id,
|
|||
|
|
"status": -5,
|
|||
|
|
"uploadStatusDesc": "parsing",
|
|||
|
|
...
|
|||
|
|
}
|
|||
|
|
self.parsing_status[log_id] = True
|
|||
|
|
|
|||
|
|
# 启动后台任务,延迟4秒后完成解析
|
|||
|
|
background_tasks.add_task(
|
|||
|
|
self._simulate_parsing,
|
|||
|
|
log_id,
|
|||
|
|
delay_seconds=4
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
return log_id
|
|||
|
|
|
|||
|
|
def _simulate_parsing(self, log_id: int, delay_seconds: int):
|
|||
|
|
time.sleep(delay_seconds)
|
|||
|
|
if log_id in self.file_records:
|
|||
|
|
self.file_records[log_id]["status"] = -5
|
|||
|
|
self.file_records[log_id]["uploadStatusDesc"] = "data.wait.confirm.newaccount"
|
|||
|
|
self.parsing_status[log_id] = False
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 错误场景模拟机制
|
|||
|
|
|
|||
|
|
### 错误触发规则
|
|||
|
|
|
|||
|
|
通过请求参数中的特殊标记触发对应的错误响应:
|
|||
|
|
|
|||
|
|
**错误码映射表:**
|
|||
|
|
```python
|
|||
|
|
ERROR_CODES = {
|
|||
|
|
"40101": {"code": "40101", "message": "appId错误"},
|
|||
|
|
"40102": {"code": "40102", "message": "appSecretCode错误"},
|
|||
|
|
"40104": {"code": "40104", "message": "可使用项目次数为0,无法创建项目"},
|
|||
|
|
"40105": {"code": "40105", "message": "只读模式下无法新建项目"},
|
|||
|
|
"40106": {"code": "40106", "message": "错误的分析类型,不在规定的取值范围内"},
|
|||
|
|
"40107": {"code": "40107", "message": "当前系统不支持的分析类型"},
|
|||
|
|
"40108": {"code": "40108", "message": "当前用户所属行社无权限"},
|
|||
|
|
"501014": {"code": "501014", "message": "无行内流水文件"},
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**检测逻辑:**
|
|||
|
|
```python
|
|||
|
|
@staticmethod
|
|||
|
|
def detect_error_marker(value: str) -> Optional[str]:
|
|||
|
|
"""检测字符串中的错误标记
|
|||
|
|
|
|||
|
|
规则:如果字符串包含 error_XXXX,则返回 XXXX
|
|||
|
|
例如:
|
|||
|
|
- "project_error_40101" -> "40101"
|
|||
|
|
- "test_error_501014" -> "501014"
|
|||
|
|
"""
|
|||
|
|
if not value:
|
|||
|
|
return None
|
|||
|
|
|
|||
|
|
import re
|
|||
|
|
pattern = r'error_(\d+)'
|
|||
|
|
match = re.search(pattern, value)
|
|||
|
|
if match:
|
|||
|
|
return match.group(1)
|
|||
|
|
return None
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**使用示例:**
|
|||
|
|
```python
|
|||
|
|
# 在服务中使用
|
|||
|
|
def get_token(request: GetTokenRequest):
|
|||
|
|
error_code = ErrorSimulator.detect_error_marker(request.projectNo)
|
|||
|
|
if error_code:
|
|||
|
|
return ErrorSimulator.build_error_response(error_code)
|
|||
|
|
|
|||
|
|
# 正常流程...
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**测试方式:**
|
|||
|
|
```python
|
|||
|
|
# 触发 40101 错误
|
|||
|
|
request_data = {
|
|||
|
|
"projectNo": "test_project_error_40101", # 包含错误标记
|
|||
|
|
"entityName": "测试企业",
|
|||
|
|
...
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 配置文件结构
|
|||
|
|
|
|||
|
|
### 响应模板配置
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
// config/responses/token.json
|
|||
|
|
{
|
|||
|
|
"success_response": {
|
|||
|
|
"code": "200",
|
|||
|
|
"data": {
|
|||
|
|
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.mock_token_{project_id}",
|
|||
|
|
"projectId": "{project_id}",
|
|||
|
|
"projectNo": "{project_no}",
|
|||
|
|
"entityName": "{entity_name}",
|
|||
|
|
"analysisType": 0
|
|||
|
|
},
|
|||
|
|
"message": "create.token.success",
|
|||
|
|
"status": "200",
|
|||
|
|
"successResponse": true
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
// config/responses/upload.json
|
|||
|
|
{
|
|||
|
|
"success_response": {
|
|||
|
|
"code": "200",
|
|||
|
|
"data": {
|
|||
|
|
"accountsOfLog": {},
|
|||
|
|
"uploadLogList": [
|
|||
|
|
{
|
|||
|
|
"logId": "{log_id}",
|
|||
|
|
"status": -5,
|
|||
|
|
"uploadStatusDesc": "data.wait.confirm.newaccount",
|
|||
|
|
...
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 全局配置
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# config/settings.py
|
|||
|
|
from pydantic import BaseSettings
|
|||
|
|
|
|||
|
|
class Settings(BaseSettings):
|
|||
|
|
APP_NAME: str = "流水分析Mock服务"
|
|||
|
|
APP_VERSION: str = "1.0.0"
|
|||
|
|
DEBUG: bool = True
|
|||
|
|
HOST: str = "0.0.0.0"
|
|||
|
|
PORT: int = 8000
|
|||
|
|
|
|||
|
|
# 模拟配置
|
|||
|
|
PARSE_DELAY_SECONDS: int = 4
|
|||
|
|
MAX_FILE_SIZE: int = 10485760 # 10MB
|
|||
|
|
|
|||
|
|
class Config:
|
|||
|
|
env_file = ".env"
|
|||
|
|
|
|||
|
|
settings = Settings()
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## API 路由实现
|
|||
|
|
|
|||
|
|
### 核心接口
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# routers/api.py
|
|||
|
|
from fastapi import APIRouter, BackgroundTasks, UploadFile, File
|
|||
|
|
|
|||
|
|
router = APIRouter()
|
|||
|
|
|
|||
|
|
# 接口1:获取Token
|
|||
|
|
@router.post("/account/common/getToken")
|
|||
|
|
async def get_token(request: GetTokenRequest):
|
|||
|
|
error_code = ErrorSimulator.detect_error_marker(request.projectNo)
|
|||
|
|
if error_code:
|
|||
|
|
return ErrorSimulator.build_error_response(error_code)
|
|||
|
|
return token_service.create_token(request)
|
|||
|
|
|
|||
|
|
# 接口2:上传文件
|
|||
|
|
@router.post("/watson/api/project/remoteUploadSplitFile")
|
|||
|
|
async def upload_file(
|
|||
|
|
background_tasks: BackgroundTasks,
|
|||
|
|
groupId: int = Form(...),
|
|||
|
|
file: UploadFile = File(...)
|
|||
|
|
):
|
|||
|
|
return file_service.upload_file(groupId, file, background_tasks)
|
|||
|
|
|
|||
|
|
# 接口3:拉取行内流水
|
|||
|
|
@router.post("/watson/api/project/getJZFileOrZjrcuFile")
|
|||
|
|
async def fetch_inner_flow(request: FetchInnerFlowRequest):
|
|||
|
|
error_code = ErrorSimulator.detect_error_marker(request.customerNo)
|
|||
|
|
if error_code:
|
|||
|
|
return ErrorSimulator.build_error_response(error_code)
|
|||
|
|
return file_service.fetch_inner_flow(request)
|
|||
|
|
|
|||
|
|
# 接口4:检查解析状态
|
|||
|
|
@router.post("/watson/api/project/upload/getpendings")
|
|||
|
|
async def check_parse_status(request: CheckParseStatusRequest):
|
|||
|
|
return file_service.check_parse_status(request.groupId, request.inprogressList)
|
|||
|
|
|
|||
|
|
# 接口5:删除文件
|
|||
|
|
@router.post("/watson/api/project/batchDeleteUploadFile")
|
|||
|
|
async def delete_files(request: dict):
|
|||
|
|
return file_service.delete_files(
|
|||
|
|
request.get("groupId"),
|
|||
|
|
request.get("logIds"),
|
|||
|
|
request.get("userId")
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 接口6:获取银行流水
|
|||
|
|
@router.post("/watson/api/project/getBSByLogId")
|
|||
|
|
async def get_bank_statement(request: GetBankStatementRequest):
|
|||
|
|
return statement_service.get_bank_statement(request)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 主应用
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# main.py
|
|||
|
|
from fastapi import FastAPI
|
|||
|
|
from routers import api
|
|||
|
|
|
|||
|
|
app = FastAPI(
|
|||
|
|
title="流水分析Mock服务",
|
|||
|
|
description="模拟流水分析平台的7个核心接口",
|
|||
|
|
version="1.0.0",
|
|||
|
|
docs_url="/docs",
|
|||
|
|
redoc_url="/redoc"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
app.include_router(api.router, tags=["流水分析接口"])
|
|||
|
|
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
import uvicorn
|
|||
|
|
uvicorn.run(app, host="0.0.0.0", port=8000)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 测试和使用说明
|
|||
|
|
|
|||
|
|
### 启动服务
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 安装依赖
|
|||
|
|
pip install -r requirements.txt
|
|||
|
|
|
|||
|
|
# 启动服务
|
|||
|
|
python main.py
|
|||
|
|
|
|||
|
|
# 或使用uvicorn启动(支持热重载)
|
|||
|
|
uvicorn main:app --reload --host 0.0.0.0 --port 8000
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 访问API文档
|
|||
|
|
|
|||
|
|
- **Swagger UI:** http://localhost:8000/docs
|
|||
|
|
- **ReDoc:** http://localhost:8000/redoc
|
|||
|
|
|
|||
|
|
### 测试示例
|
|||
|
|
|
|||
|
|
#### 1. 正常流程测试
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
import requests
|
|||
|
|
|
|||
|
|
# 获取Token
|
|||
|
|
response = requests.post(
|
|||
|
|
"http://localhost:8000/account/common/getToken",
|
|||
|
|
json={
|
|||
|
|
"projectNo": "test_project_001",
|
|||
|
|
"entityName": "测试企业",
|
|||
|
|
"userId": "902001",
|
|||
|
|
"userName": "902001",
|
|||
|
|
"orgCode": "902000"
|
|||
|
|
}
|
|||
|
|
)
|
|||
|
|
result = response.json()
|
|||
|
|
token = result["data"]["token"]
|
|||
|
|
project_id = result["data"]["projectId"]
|
|||
|
|
|
|||
|
|
# 上传文件
|
|||
|
|
files = {"file": ("test.csv", open("test.csv", "rb"), "text/csv")}
|
|||
|
|
response = requests.post(
|
|||
|
|
"http://localhost:8000/watson/api/project/remoteUploadSplitFile",
|
|||
|
|
files=files,
|
|||
|
|
data={"groupId": project_id},
|
|||
|
|
headers={"X-Xencio-Client-Id": "26e5b9239853436b85c623f4b7a6d0e6"}
|
|||
|
|
)
|
|||
|
|
log_id = response.json()["data"]["uploadLogList"][0]["logId"]
|
|||
|
|
|
|||
|
|
# 轮询检查解析状态
|
|||
|
|
import time
|
|||
|
|
for i in range(10):
|
|||
|
|
response = requests.post(
|
|||
|
|
"http://localhost:8000/watson/api/project/upload/getpendings",
|
|||
|
|
json={"groupId": project_id, "inprogressList": str(log_id)},
|
|||
|
|
headers={"X-Xencio-Client-Id": "26e5b9239853436b85c623f4b7a6d0e6"}
|
|||
|
|
)
|
|||
|
|
result = response.json()
|
|||
|
|
if not result["data"]["parsing"]:
|
|||
|
|
print("解析完成")
|
|||
|
|
break
|
|||
|
|
time.sleep(1)
|
|||
|
|
|
|||
|
|
# 获取银行流水
|
|||
|
|
response = requests.post(
|
|||
|
|
"http://localhost:8000/watson/api/project/getBSByLogId",
|
|||
|
|
json={
|
|||
|
|
"groupId": project_id,
|
|||
|
|
"logId": log_id,
|
|||
|
|
"pageNow": 1,
|
|||
|
|
"pageSize": 10
|
|||
|
|
},
|
|||
|
|
headers={"X-Xencio-Client-Id": "26e5b9239853436b85c623f4b7a6d0e6"}
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 2. 错误场景测试
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# 触发 40101 错误(appId错误)
|
|||
|
|
response = requests.post(
|
|||
|
|
"http://localhost:8000/account/common/getToken",
|
|||
|
|
json={
|
|||
|
|
"projectNo": "test_project_error_40101", # 包含错误标记
|
|||
|
|
"entityName": "测试企业",
|
|||
|
|
"userId": "902001",
|
|||
|
|
"userName": "902001",
|
|||
|
|
"orgCode": "902000"
|
|||
|
|
}
|
|||
|
|
)
|
|||
|
|
# 返回: {"code": "40101", "message": "appId错误", ...}
|
|||
|
|
|
|||
|
|
# 触发 501014 错误(无行内流水文件)
|
|||
|
|
response = requests.post(
|
|||
|
|
"http://localhost:8000/watson/api/project/getJZFileOrZjrcuFile",
|
|||
|
|
json={
|
|||
|
|
"groupId": 1,
|
|||
|
|
"customerNo": "test_error_501014", # 包含错误标记
|
|||
|
|
"dataChannelCode": "ZJRCU",
|
|||
|
|
"requestDateId": 20260302,
|
|||
|
|
"dataStartDateId": 20260201,
|
|||
|
|
"dataEndDateId": 20260228,
|
|||
|
|
"uploadUserId": 902001
|
|||
|
|
}
|
|||
|
|
)
|
|||
|
|
# 返回: {"code": "501014", "message": "无行内流水文件", ...}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 配置修改
|
|||
|
|
|
|||
|
|
- 修改 `config/responses/` 下的JSON文件可以自定义响应数据
|
|||
|
|
- 修改 `config/settings.py` 可以调整延迟时间、端口等配置
|
|||
|
|
- 支持 `.env` 文件覆盖配置
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 依赖清单
|
|||
|
|
|
|||
|
|
```txt
|
|||
|
|
# requirements.txt
|
|||
|
|
fastapi==0.104.1
|
|||
|
|
uvicorn[standard]==0.24.0
|
|||
|
|
pydantic==2.5.0
|
|||
|
|
python-multipart==0.0.6
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 使用场景
|
|||
|
|
|
|||
|
|
### A. 开发阶段测试
|
|||
|
|
在业务代码开发过程中,修改配置文件 `application-dev.yml`,将 `lsfx.api.base-url` 改为 `http://localhost:8000`,启动Mock服务器后,业务代码即可连接Mock服务进行测试。
|
|||
|
|
|
|||
|
|
### B. 完全替换测试
|
|||
|
|
直接使用 Mock 服务器进行接口测试,验证业务逻辑的正确性。生产环境切换到真实服务。
|
|||
|
|
|
|||
|
|
### C. CI/CD 集成
|
|||
|
|
在持续集成流程中使用 Mock 服务器,自动化测试接口调用逻辑。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 扩展性考虑
|
|||
|
|
|
|||
|
|
### 后续可能的增强功能
|
|||
|
|
|
|||
|
|
1. **数据持久化** - 如需保留历史记录,可集成SQLite
|
|||
|
|
2. **更复杂的场景模拟** - 支持配置文件定义多个场景
|
|||
|
|
3. **请求日志记录** - 记录所有请求用于调试
|
|||
|
|
4. **Web管理界面** - 可视化管理Mock数据和状态
|
|||
|
|
5. **Docker部署** - 提供Dockerfile方便部署
|
|||
|
|
|
|||
|
|
当前设计已满足核心需求,保持简洁实用。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 总结
|
|||
|
|
|
|||
|
|
这是一个**配置驱动、轻量级、易于使用**的 Mock 服务器设计,核心特点:
|
|||
|
|
|
|||
|
|
✅ **完整性** - 覆盖所有7个核心接口
|
|||
|
|
✅ **真实性** - 模拟文件解析延迟等真实场景
|
|||
|
|
✅ **灵活性** - 配置文件驱动,错误场景可触发
|
|||
|
|
✅ **易用性** - 自动API文档,零配置启动
|
|||
|
|
✅ **可维护** - 代码结构清晰,与Java项目对应
|
|||
|
|
|
|||
|
|
满足您的Mock测试需求,提升开发和测试效率。
|