Files
rust-user-api/tests/integration_tests.rs
enoch bb539e5cba feat: [阶段7] 完善 API 文档和测试用例
- 创建详细的 API 文档(docs/api.md),包含所有端点说明和示例
- 实现完整的单元测试套件,覆盖所有核心功能:
  * 内存存储操作测试
  * 用户请求验证测试
  * 数据模型转换测试
  * 错误处理测试
  * 配置管理测试
  * 用户认证服务测试
- 添加集成测试框架(tests/integration_tests.rs)
- 修复 OpenSSL 依赖问题,使用 rustls-tls
- 增强测试脚本,包含更多验证场景
- 所有测试通过,确保代码质量和稳定性
2025-08-04 17:58:47 +08:00

299 lines
8.3 KiB
Rust

//! 集成测试
use reqwest;
use serde_json::{json, Value};
use std::collections::HashMap;
use tokio;
const BASE_URL: &str = "http://127.0.0.1:3000";
/// 测试辅助函数:创建 HTTP 客户端
fn create_client() -> reqwest::Client {
reqwest::Client::new()
}
/// 测试辅助函数:解析 JSON 响应
async fn parse_json_response(response: reqwest::Response) -> Result<Value, Box<dyn std::error::Error>> {
let text = response.text().await?;
let json: Value = serde_json::from_str(&text)?;
Ok(json)
}
#[tokio::test]
async fn test_health_check() {
let client = create_client();
let response = client
.get(&format!("{}/health", BASE_URL))
.send()
.await
.expect("Failed to send request");
assert_eq!(response.status(), 200);
let json = parse_json_response(response).await.expect("Failed to parse JSON");
assert_eq!(json["status"], "healthy");
assert!(json["timestamp"].is_string());
}
#[tokio::test]
async fn test_root_endpoint() {
let client = create_client();
let response = client
.get(&format!("{}/", BASE_URL))
.send()
.await
.expect("Failed to send request");
assert_eq!(response.status(), 200);
let json = parse_json_response(response).await.expect("Failed to parse JSON");
assert_eq!(json["message"], "欢迎使用 Rust User API");
assert_eq!(json["version"], "0.1.0");
}
#[tokio::test]
async fn test_user_lifecycle() {
let client = create_client();
// 1. 获取初始用户列表(应该为空)
let response = client
.get(&format!("{}/api/users", BASE_URL))
.send()
.await
.expect("Failed to get users");
assert_eq!(response.status(), 200);
let users = parse_json_response(response).await.expect("Failed to parse JSON");
assert!(users.is_array());
// 2. 创建新用户
let user_data = json!({
"username": "testuser_integration",
"email": "integration@example.com",
"password": "password123"
});
let response = client
.post(&format!("{}/api/users", BASE_URL))
.json(&user_data)
.send()
.await
.expect("Failed to create user");
assert_eq!(response.status(), 201);
let created_user = parse_json_response(response).await.expect("Failed to parse JSON");
assert_eq!(created_user["username"], "testuser_integration");
assert_eq!(created_user["email"], "integration@example.com");
assert!(created_user["id"].is_string());
assert!(created_user["created_at"].is_string());
let user_id = created_user["id"].as_str().unwrap();
// 3. 获取创建的用户
let response = client
.get(&format!("{}/api/users/{}", BASE_URL, user_id))
.send()
.await
.expect("Failed to get user");
assert_eq!(response.status(), 200);
let fetched_user = parse_json_response(response).await.expect("Failed to parse JSON");
assert_eq!(fetched_user["id"], user_id);
assert_eq!(fetched_user["username"], "testuser_integration");
// 4. 更新用户
let update_data = json!({
"username": "updated_testuser",
"email": "updated@example.com"
});
let response = client
.put(&format!("{}/api/users/{}", BASE_URL, user_id))
.json(&update_data)
.send()
.await
.expect("Failed to update user");
assert_eq!(response.status(), 200);
let updated_user = parse_json_response(response).await.expect("Failed to parse JSON");
assert_eq!(updated_user["username"], "updated_testuser");
assert_eq!(updated_user["email"], "updated@example.com");
// 5. 删除用户
let response = client
.delete(&format!("{}/api/users/{}", BASE_URL, user_id))
.send()
.await
.expect("Failed to delete user");
assert_eq!(response.status(), 204);
// 6. 验证用户已被删除
let response = client
.get(&format!("{}/api/users/{}", BASE_URL, user_id))
.send()
.await
.expect("Failed to get deleted user");
assert_eq!(response.status(), 404);
}
#[tokio::test]
async fn test_user_validation() {
let client = create_client();
// 测试无效的用户数据
let invalid_user_data = json!({
"username": "ab", // 太短
"email": "invalid-email", // 无效邮箱
"password": "123" // 太短
});
let response = client
.post(&format!("{}/api/users", BASE_URL))
.json(&invalid_user_data)
.send()
.await
.expect("Failed to send request");
assert_eq!(response.status(), 400);
let error_response = parse_json_response(response).await.expect("Failed to parse JSON");
assert!(error_response["error"].is_string());
assert_eq!(error_response["status"], 400);
}
#[tokio::test]
async fn test_duplicate_username() {
let client = create_client();
let user_data = json!({
"username": "duplicate_test",
"email": "duplicate1@example.com",
"password": "password123"
});
// 创建第一个用户
let response = client
.post(&format!("{}/api/users", BASE_URL))
.json(&user_data)
.send()
.await
.expect("Failed to create first user");
assert_eq!(response.status(), 201);
// 尝试创建相同用户名的用户
let duplicate_user_data = json!({
"username": "duplicate_test", // 相同用户名
"email": "duplicate2@example.com",
"password": "password123"
});
let response = client
.post(&format!("{}/api/users", BASE_URL))
.json(&duplicate_user_data)
.send()
.await
.expect("Failed to send duplicate request");
assert_eq!(response.status(), 409);
let error_response = parse_json_response(response).await.expect("Failed to parse JSON");
assert!(error_response["error"].as_str().unwrap().contains("用户名已存在"));
}
#[tokio::test]
async fn test_login_flow() {
let client = create_client();
// 1. 创建测试用户
let user_data = json!({
"username": "login_test",
"email": "login@example.com",
"password": "password123"
});
let response = client
.post(&format!("{}/api/users", BASE_URL))
.json(&user_data)
.send()
.await
.expect("Failed to create user");
assert_eq!(response.status(), 201);
// 2. 测试正确的登录凭据
let login_data = json!({
"username": "login_test",
"password": "password123"
});
let response = client
.post(&format!("{}/api/auth/login", BASE_URL))
.json(&login_data)
.send()
.await
.expect("Failed to login");
assert_eq!(response.status(), 200);
let login_response = parse_json_response(response).await.expect("Failed to parse JSON");
assert!(login_response["token"].is_string());
assert!(login_response["user"]["id"].is_string());
assert_eq!(login_response["user"]["username"], "login_test");
// 3. 测试错误的密码
let wrong_login_data = json!({
"username": "login_test",
"password": "wrongpassword"
});
let response = client
.post(&format!("{}/api/auth/login", BASE_URL))
.json(&wrong_login_data)
.send()
.await
.expect("Failed to send wrong login");
assert_eq!(response.status(), 401);
// 4. 测试不存在的用户
let nonexistent_login_data = json!({
"username": "nonexistent_user",
"password": "password123"
});
let response = client
.post(&format!("{}/api/auth/login", BASE_URL))
.json(&nonexistent_login_data)
.send()
.await
.expect("Failed to send nonexistent login");
assert_eq!(response.status(), 404);
}
#[tokio::test]
async fn test_not_found_endpoints() {
let client = create_client();
// 测试不存在的用户 ID
let response = client
.get(&format!("{}/api/users/00000000-0000-0000-0000-000000000000", BASE_URL))
.send()
.await
.expect("Failed to send request");
assert_eq!(response.status(), 404);
// 测试不存在的端点
let response = client
.get(&format!("{}/api/nonexistent", BASE_URL))
.send()
.await
.expect("Failed to send request");
assert_eq!(response.status(), 404);
}