""" 单元测试套件 - API客户端测试 测试范围: 1. API客户端基础功能 2. 认证API测试 3. 用户API测试 4. 角色API测试 作者: 张翔 日期: 2026-04-01 """ import pytest from unittest.mock import Mock, AsyncMock, patch from api.base_api import BaseAPIClient, AsyncAPIClient from api.auth_api import AuthAPI from api.user_api import UserAPI from api.role_api import RoleAPI @pytest.mark.unit class TestBaseAPI: """API客户端基础功能测试""" def test_base_api_initialization(self): """ UNIT-API-01: API客户端初始化测试 验证点: 1. 正确初始化客户端 2. 设置基础URL 3. 设置超时时间 """ base_url = "http://localhost:8084" api = BaseAPIClient(base_url=base_url, timeout=30) assert api.base_url == base_url assert api.timeout == 30 assert api.session is not None def test_api_headers_generation(self): """ UNIT-API-02: API请求头生成测试 验证点: 1. 正确生成基础请求头 2. 包含认证Token时添加Authorization """ api = BaseAPIClient() api.token = "test_token_123" headers = api._get_headers(include_auth=True) assert "Content-Type" in headers assert "Authorization" in headers assert headers["Authorization"] == "Bearer test_token_123" headers_no_auth = api._get_headers(include_auth=False) assert "Authorization" not in headers_no_auth @pytest.mark.unit class TestAuthAPI: """认证API测试""" @pytest.mark.asyncio async def test_login_success(self): """ UNIT-AUTH-01: 登录成功测试 验证点: 1. 正确发送登录请求 2. 返回Token 3. 返回用户信息 """ mock_client = Mock() mock_client.post = AsyncMock( return_value=Mock( status_code=200, json=Mock(return_value={ "token": "test_token_123", "userId": 1, "username": "admin" }) ) ) auth_api = AuthAPI(mock_client) response = await auth_api.login("admin", "admin123") assert response.status_code == 200 assert response.json()["token"] == "test_token_123" @pytest.mark.asyncio async def test_login_failure(self): """ UNIT-AUTH-02: 登录失败测试 验证点: 1. 错误密码返回401 2. 错误信息不泄露敏感信息 """ mock_client = Mock() mock_client.post = AsyncMock( return_value=Mock( status_code=401, json=Mock(return_value={ "error": "Invalid credentials" }) ) ) auth_api = AuthAPI(mock_client) response = await auth_api.login("admin", "wrong_password") assert response.status_code == 401 @pytest.mark.asyncio async def test_logout(self): """ UNIT-AUTH-03: 登出测试 验证点: 1. 正确发送登出请求 2. 返回成功状态 """ mock_client = Mock() mock_client.post = AsyncMock( return_value=Mock(status_code=200) ) auth_api = AuthAPI(mock_client) response = await auth_api.logout() assert response.status_code == 200 @pytest.mark.unit class TestUserAPI: """用户API测试""" @pytest.mark.asyncio async def test_get_users_by_page(self): """ UNIT-USER-01: 分页获取用户列表测试 验证点: 1. 正确发送分页参数 2. 返回分页数据 3. 包含总数信息 """ mock_client = Mock() mock_client.get = AsyncMock( return_value=Mock( status_code=200, json=Mock(return_value={ "content": [ {"id": 1, "username": "admin"}, {"id": 2, "username": "user"} ], "totalElements": 2, "totalPages": 1, "size": 10, "number": 0 }) ) ) user_api = UserAPI(mock_client) response = await user_api.get_users_by_page(page=0, size=10) assert response.status_code == 200 assert len(response.json()["content"]) == 2 assert response.json()["totalElements"] == 2 @pytest.mark.asyncio async def test_create_user(self): """ UNIT-USER-02: 创建用户测试 验证点: 1. 正确发送用户数据 2. 返回创建的用户ID 3. 验证必填字段 """ mock_client = Mock() mock_client.post = AsyncMock( return_value=Mock( status_code=201, json=Mock(return_value={ "id": 3, "username": "new_user", "email": "new_user@test.com" }) ) ) user_api = UserAPI(mock_client) user_data = { "username": "new_user", "password": "Test123!@#", "email": "new_user@test.com", "phone": "13800138000" } response = await user_api.create_user(user_data) assert response.status_code == 201 assert response.json()["id"] == 3 @pytest.mark.asyncio async def test_update_user(self): """ UNIT-USER-03: 更新用户测试 验证点: 1. 正确发送更新数据 2. 返回更新后的用户信息 3. 部分更新支持 """ mock_client = Mock() mock_client.put = AsyncMock( return_value=Mock( status_code=200, json=Mock(return_value={ "id": 1, "email": "updated@test.com" }) ) ) user_api = UserAPI(mock_client) update_data = {"email": "updated@test.com"} response = await user_api.update_user(1, update_data) assert response.status_code == 200 assert response.json()["email"] == "updated@test.com" @pytest.mark.asyncio async def test_delete_user(self): """ UNIT-USER-04: 删除用户测试 验证点: 1. 正确发送删除请求 2. 返回成功状态 """ mock_client = Mock() mock_client.delete = AsyncMock( return_value=Mock(status_code=204) ) user_api = UserAPI(mock_client) response = await user_api.delete_user(1) assert response.status_code == 204 @pytest.mark.asyncio async def test_search_users(self): """ UNIT-USER-05: 搜索用户测试 验证点: 1. 正确发送搜索关键词 2. 返回匹配结果 """ mock_client = Mock() mock_client.get = AsyncMock( return_value=Mock( status_code=200, json=Mock(return_value={ "content": [ {"id": 1, "username": "admin"} ], "totalElements": 1 }) ) ) user_api = UserAPI(mock_client) response = await user_api.get_users_by_page(username="admin") assert response.status_code == 200 assert len(response.json()["content"]) == 1 @pytest.mark.unit class TestRoleAPI: """角色API测试""" @pytest.mark.asyncio async def test_get_roles(self): """ UNIT-ROLE-01: 获取角色列表测试 验证点: 1. 正确返回角色列表 2. 包含角色权限信息 """ mock_client = Mock() mock_client.get = AsyncMock( return_value=Mock( status_code=200, json=Mock(return_value=[ {"id": 1, "roleName": "管理员", "roleKey": "admin"}, {"id": 2, "roleName": "普通用户", "roleKey": "user"} ]) ) ) role_api = RoleAPI(mock_client) response = await role_api.get_role_list() assert response.status_code == 200 assert len(response.json()) == 2 @pytest.mark.asyncio async def test_assign_permissions(self): """ UNIT-ROLE-02: 分配权限测试 验证点: 1. 正确发送权限数据 2. 返回成功状态 """ mock_client = Mock() mock_client.post = AsyncMock( return_value=Mock(status_code=200) ) role_api = RoleAPI(mock_client) permission_ids = [1, 2, 3] response = await role_api.assign_permissions(1, permission_ids) assert response.status_code == 200