Files
mock-server/tests/v2_integration_test.rs
CNWei d364307131 feat: mock配置迁移至JSON格式并修复body匹配
- 将mock配置从YAML格式迁移到JSON格式
- 修复JSON字符串格式body匹配失败问题
- 添加MCP功能模块
- 更新mock-spec.md规范文档

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 09:43:11 +08:00

227 lines
7.4 KiB
Rust
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use std::path::Path;
use std::collections::HashMap;
use serde_json::json;
use mock_server::models::Payload;
use mock_server::loader::MockLoader;
use mock_server::router::MockRouter;
/// 加载 v1 目录的 mock 规则
fn load_v1_mocks() -> HashMap<String, Vec<mock_server::models::MockRule>> {
let v1_path = Path::new("./mocks/v1");
MockLoader::load_all_from_dir(v1_path)
}
// ========== 模块一:验证所有 JSON 文件正确加载 ==========
#[test]
fn test_v1_load_all_mocks() {
let index = load_v1_mocks();
// 验证索引键存在
assert!(index.contains_key("v1"), "应包含 'v1' 索引键");
// 验证规则总数
let total: usize = index.values().map(|v| v.len()).sum();
assert!(total >= 10, "v1 目录应有至少 10 个 mock 规则");
}
// ========== 模块二JSON Payload 测试 ==========
#[test]
fn test_v1_json_login() {
let index = load_v1_mocks();
let router = MockRouter::new(index);
let mut headers = HashMap::new();
headers.insert("Content-Type".to_string(), "application/json".to_string());
headers.insert("Authorization".to_string(), "eyJhbGciOiJIUzI1NiIsInR5cCI6".to_string());
headers.insert("host".to_string(), "127.0.0.1:8080".to_string());
let payload = Payload::Json(json!({
"username": "user001",
"password": "password123"
}));
let matched = router.match_rule("POST", "/v1/auth/login", &HashMap::new(), &headers, &payload);
assert!(matched.is_some(), "JSON 登录应匹配成功");
let rule = matched.unwrap();
assert_eq!(rule.name, "user_login_001");
assert_eq!(rule.response.status, 200);
}
#[test]
fn test_v1_json_register() {
let index = load_v1_mocks();
let router = MockRouter::new(index);
let mut headers = HashMap::new();
headers.insert("Content-Type".to_string(), "application/json".to_string());
let payload = Payload::Json(json!({
"username": "newuser",
"password": "newpass123",
"email": "newuser@example.com"
}));
let matched = router.match_rule("POST", "/v1/auth/register", &HashMap::new(), &headers, &payload);
assert!(matched.is_some(), "JSON 注册应匹配成功");
let rule = matched.unwrap();
assert_eq!(rule.name, "user_register");
assert_eq!(rule.response.status, 201);
}
// ========== 模块三Form Payload 测试 ==========
#[test]
fn test_v1_form_login() {
let index = load_v1_mocks();
let router = MockRouter::new(index);
let mut headers = HashMap::new();
headers.insert("Content-Type".to_string(), "application/x-www-form-urlencoded".to_string());
let mut form_data = HashMap::new();
form_data.insert("username".to_string(), "formuser".to_string());
form_data.insert("password".to_string(), "formpass".to_string());
let payload = Payload::Form(form_data);
let matched = router.match_rule("POST", "/v1/user/login/form", &HashMap::new(), &headers, &payload);
assert!(matched.is_some(), "Form 登录应匹配成功");
assert_eq!(matched.unwrap().name, "_user_login_form");
}
// ========== 模块四Text Payload 测试 ==========
#[test]
fn test_v1_text_echo() {
let index = load_v1_mocks();
let router = MockRouter::new(index);
let mut headers = HashMap::new();
headers.insert("Content-Type".to_string(), "text/plain".to_string());
let payload = Payload::Text("Hello V1 Mock Server".to_string());
let matched = router.match_rule("POST", "/v1/user/echo", &HashMap::new(), &headers, &payload);
assert!(matched.is_some(), "Text 回显应匹配成功");
let rule = matched.unwrap();
assert_eq!(rule.name, "user_echo");
assert!(rule.response.body.contains("Echo from V1"));
}
// ========== 模块五XML Payload 测试 ==========
#[test]
fn test_v1_xml_export() {
let index = load_v1_mocks();
let router = MockRouter::new(index);
let mut headers = HashMap::new();
headers.insert("Content-Type".to_string(), "application/xml".to_string());
let xml_body = r#"<?xml version="1.0" encoding="UTF-8"?><request><userId>10001</userId><format>xml</format></request>"#;
let payload = Payload::Xml(xml_body.to_string());
let matched = router.match_rule("POST", "/v1/data/export", &HashMap::new(), &headers, &payload);
assert!(matched.is_some(), "XML 导出应匹配成功");
assert_eq!(matched.unwrap().name, "data_export");
}
// ========== 模块六Multipart Payload 测试 ==========
#[test]
fn test_v1_multipart_upload() {
let index = load_v1_mocks();
let router = MockRouter::new(index);
let mut headers = HashMap::new();
headers.insert("Content-Type".to_string(), "multipart/form-data".to_string());
let mut multipart_data = HashMap::new();
multipart_data.insert("avatar1".to_string(), "file_content".to_string());
multipart_data.insert("description1".to_string(), "user avatar".to_string());
let payload = Payload::Multipart(multipart_data);
let matched = router.match_rule("POST", "/v1/user/avatar", &HashMap::new(), &headers, &payload);
assert!(matched.is_some(), "Multipart 上传应匹配成功");
assert_eq!(matched.unwrap().name, "user_upload_avatar_001");
}
// ========== 模块七None Payload 测试 (GET 无 Body) ==========
#[test]
fn test_v1_health_check() {
let index = load_v1_mocks();
let router = MockRouter::new(index);
let payload = Payload::None;
let matched = router.match_rule("GET", "/v1/health", &HashMap::new(), &HashMap::new(), &payload);
assert!(matched.is_some(), "健康检查应匹配成功");
let rule = matched.unwrap();
assert_eq!(rule.name, "health_check");
assert_eq!(rule.response.status, 200);
}
#[test]
fn test_v1_get_profile() {
let index = load_v1_mocks();
let router = MockRouter::new(index);
let mut headers = HashMap::new();
headers.insert("Authorization".to_string(), "Bearer v1_test_token".to_string());
let payload = Payload::None;
let matched = router.match_rule("GET", "/v1/user/profile", &HashMap::new(), &headers, &payload);
assert!(matched.is_some(), "获取用户信息应匹配成功");
assert_eq!(matched.unwrap().name, "user_profile");
}
// ========== 模块八Query Params 测试 ==========
#[test]
fn test_v1_query_params() {
let index = load_v1_mocks();
let router = MockRouter::new(index);
let mut query = HashMap::new();
query.insert("format".to_string(), "json".to_string());
let payload = Payload::None;
let matched = router.match_rule("GET", "/v1/user/download", &query, &HashMap::new(), &payload);
assert!(matched.is_some(), "带 query params 的下载应匹配成功");
let rule = matched.unwrap();
assert_eq!(rule.name, "user_download");
assert!(rule.response.body.starts_with("file://"));
}
// ========== 模块九Header 匹配测试 ==========
#[test]
fn test_v1_header_required() {
let index = load_v1_mocks();
let router = MockRouter::new(index);
// 无 Authorization header 不应匹配
let payload = Payload::None;
let no_match = router.match_rule("GET", "/v1/user/profile", &HashMap::new(), &HashMap::new(), &payload);
assert!(no_match.is_none(), "无 Authorization 不应匹配");
// 有正确的 Authorization header 应匹配
let mut headers = HashMap::new();
headers.insert("Authorization".to_string(), "Bearer v1_test_token".to_string());
let matched = router.match_rule("GET", "/v1/user/profile", &HashMap::new(), &headers, &payload);
assert!(matched.is_some(), "有 Authorization 应匹配");
}