more_agent/tests/test_basic.py

249 lines
8.7 KiB
Python
Raw Normal View History

2026-05-12 05:03:18 +00:00
"""用户管理服务 - 基础单元测试模块。
使用 pytest httpx API 接口进行测试
"""
import pytest
from fastapi.testclient import TestClient
from app.main import app
from app.database import db
# ──────────────────────────────────────────────
# 测试客户端
# ──────────────────────────────────────────────
@pytest.fixture(autouse=True)
def reset_database():
"""每个测试用例执行前重置数据库状态。
保存原始数据并在测试后恢复避免测试间的数据污染
"""
# 清空数据库并重新初始化种子数据
db._users.clear()
db._username_index.clear()
db._init_seed_data()
yield
client = TestClient(app)
# ──────────────────────────────────────────────
# 健康检查测试
# ──────────────────────────────────────────────
class TestHealthCheck:
"""健康检查接口测试类。"""
def test_health_check_returns_ok(self):
"""测试健康检查接口返回状态 ok。"""
response = client.get("/health")
assert response.status_code == 200
data = response.json()
assert data["status"] == "ok"
assert data["service"] == "user-management-service"
assert data["total_users"] >= 3
# ──────────────────────────────────────────────
# 用户创建测试
# ──────────────────────────────────────────────
class TestCreateUser:
"""用户注册接口测试类。"""
def test_create_user_success(self):
"""测试成功创建用户。"""
response = client.post(
"/api/users",
json={
"username": "newuser",
"email": "newuser@example.com",
"password": "password123",
},
)
assert response.status_code == 201
data = response.json()
assert data["username"] == "newuser"
assert data["email"] == "newuser@example.com"
assert data["is_active"] is True
assert "id" in data
assert "created_at" in data
def test_create_user_duplicate_username(self):
"""测试创建重复用户名应返回 409。"""
response = client.post(
"/api/users",
json={
"username": "alice",
"email": "alice2@example.com",
"password": "password123",
},
)
assert response.status_code == 409
assert "已被占用" in response.json()["detail"]
def test_create_user_duplicate_email(self):
"""测试创建重复邮箱应返回 409。"""
response = client.post(
"/api/users",
json={
"username": "alice2",
"email": "alice@example.com",
"password": "password123",
},
)
assert response.status_code == 409
assert "已被注册" in response.json()["detail"]
def test_create_user_validation_error(self):
"""测试用户名太短应返回 422。"""
response = client.post(
"/api/users",
json={
"username": "ab",
"email": "test@example.com",
"password": "password123",
},
)
assert response.status_code == 422
# ──────────────────────────────────────────────
# 用户查询测试
# ──────────────────────────────────────────────
class TestGetUsers:
"""用户查询接口测试类。"""
def test_get_all_users(self):
"""测试获取所有用户(分页)。"""
response = client.get("/api/users?skip=0&limit=10")
assert response.status_code == 200
data = response.json()
assert len(data) >= 3
# 验证返回的字段不包含密码
for user in data:
assert "password" not in user
assert "hashed_password" not in user
def test_get_user_by_id_success(self):
"""测试通过 ID 获取用户成功。"""
response = client.get("/api/users/user-001")
assert response.status_code == 200
data = response.json()
assert data["username"] == "alice"
assert data["email"] == "alice@example.com"
def test_get_user_by_id_not_found(self):
"""测试获取不存在的用户返回 404。"""
response = client.get("/api/users/user-999")
assert response.status_code == 404
def test_get_users_pagination(self):
"""测试分页参数生效。"""
response = client.get("/api/users?skip=0&limit=1")
assert response.status_code == 200
data = response.json()
assert len(data) == 1
# ──────────────────────────────────────────────
# 用户更新测试
# ──────────────────────────────────────────────
class TestUpdateUser:
"""用户更新接口测试类。"""
def test_update_username_success(self):
"""测试成功更新用户名。"""
response = client.put(
"/api/users/user-001",
json={"username": "alice_updated"},
)
assert response.status_code == 200
data = response.json()
assert data["username"] == "alice_updated"
def test_update_user_not_found(self):
"""测试更新不存在的用户返回 404。"""
response = client.put(
"/api/users/user-999",
json={"username": "new_name"},
)
assert response.status_code == 404
def test_update_username_conflict(self):
"""测试更新为已存在的用户名返回 409。"""
response = client.put(
"/api/users/user-001",
json={"username": "bob"},
)
assert response.status_code == 409
# ──────────────────────────────────────────────
# 用户删除测试
# ──────────────────────────────────────────────
class TestDeleteUser:
"""用户删除接口测试类。"""
def test_delete_user_success(self):
"""测试成功删除用户。"""
response = client.delete("/api/users/user-001")
assert response.status_code == 200
data = response.json()
assert "成功删除" in data["message"]
# 验证用户确实被删除
get_response = client.get("/api/users/user-001")
assert get_response.status_code == 404
def test_delete_user_not_found(self):
"""测试删除不存在的用户返回 404。"""
response = client.delete("/api/users/user-999")
assert response.status_code == 404
# ──────────────────────────────────────────────
# 用户登录测试
# ──────────────────────────────────────────────
class TestLogin:
"""用户登录接口测试类。"""
def test_login_success(self):
"""测试使用正确的用户名和密码登录成功。"""
response = client.post(
"/api/users/login",
json={"username": "alice", "password": "abc123"},
)
assert response.status_code == 200
data = response.json()
assert data["username"] == "alice"
def test_login_wrong_password(self):
"""测试使用错误密码登录返回 401。"""
response = client.post(
"/api/users/login",
json={"username": "alice", "password": "wrong_password"},
)
assert response.status_code == 401
def test_login_user_not_found(self):
"""测试使用不存在的用户名登录返回 401。"""
response = client.post(
"/api/users/login",
json={"username": "nonexistent", "password": "password123"},
)
assert response.status_code == 401