You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

7.4 KiB

微信服务测试套件实现

日期: 2026-01-29
类型: 测试
影响范围: 微信登录服务测试

概述

完成微信登录服务的完整测试套件,包括单元测试和集成测试,覆盖所有核心功能。

测试文件

1. 单元测试

文件: server/tests/unit/test_wechat_service.py

测试覆盖

TestGenerateQrcode - 生成二维码测试
  • test_generate_qrcode_mp_platform - 测试生成公众号二维码
  • test_generate_qrcode_open_platform - 测试生成开放平台二维码
  • test_generate_qrcode_invalid_platform - 测试无效平台类型
TestHandleCallback - 处理回调测试
  • test_handle_callback_success - 测试成功处理回调
  • test_handle_callback_invalid_platform - 测试无效平台
TestGetLoginResult - 获取登录结果测试
  • test_get_login_result_pending - 测试等待中状态
  • test_get_login_result_new_user - 测试新用户自动注册
  • test_get_login_result_existing_user - 测试已存在用户登录
TestBindWechat - 绑定微信测试
  • test_bind_wechat_success - 测试成功绑定
  • test_bind_wechat_already_bound - 测试微信已被其他用户绑定
TestUnbindWechat - 解绑微信测试
  • test_unbind_wechat_success - 测试成功解绑
  • test_unbind_wechat_user_not_found - 测试用户不存在

2. 集成测试

文件: server/tests/integration/test_wechat_api.py

测试覆盖

TestWechatQrcodeAPI - 二维码 API 测试
  • test_get_qrcode_mp_platform - 测试获取公众号二维码
  • test_get_qrcode_open_platform - 测试获取开放平台二维码
  • test_get_qrcode_invalid_platform - 测试无效平台
TestWechatLoginResultAPI - 登录结果 API 测试
  • test_get_login_result_pending - 测试等待中状态
  • test_get_login_result_success - 测试登录成功
TestWechatBindAPI - 绑定 API 测试
  • test_bind_wechat_success - 测试成功绑定
  • test_bind_wechat_unauthorized - 测试未认证
  • test_bind_wechat_invalid_platform - 测试无效平台
TestWechatUnbindAPI - 解绑 API 测试
  • test_unbind_wechat_success - 测试成功解绑
  • test_unbind_wechat_unauthorized - 测试未认证
TestWechatCallbackAPI - 回调 API 测试
  • test_callback_success - 测试成功处理回调
  • test_callback_error - 测试回调错误

测试执行结果

单元测试

$ docker exec jointo-server-app pytest tests/unit/test_wechat_service.py -v

============================= test session starts ==============================
platform linux -- Python 3.12.12, pytest-7.4.4, pluggy-1.6.0
cachedir: .pytest_cache
rootdir: /app
configfile: pytest.ini
plugins: cov-4.1.0, asyncio-0.23.3, anyio-4.12.1
asyncio: mode=Mode.AUTO
collecting ... collected 12 items

tests/unit/test_wechat_service.py::TestGenerateQrcode::test_generate_qrcode_mp_platform PASSED [  8%]
tests/unit/test_wechat_service.py::TestGenerateQrcode::test_generate_qrcode_open_platform PASSED [ 16%]
tests/unit/test_wechat_service.py::TestGenerateQrcode::test_generate_qrcode_invalid_platform PASSED [ 25%]
tests/unit/test_wechat_service.py::TestHandleCallback::test_handle_callback_success PASSED [ 33%]
tests/unit/test_wechat_service.py::TestHandleCallback::test_handle_callback_invalid_platform PASSED [ 41%]
tests/unit/test_wechat_service.py::TestGetLoginResult::test_get_login_result_pending PASSED [ 50%]
tests/unit/test_wechat_service.py::TestGetLoginResult::test_get_login_result_new_user PASSED [ 58%]
tests/unit/test_wechat_service.py::TestGetLoginResult::test_get_login_result_existing_user PASSED [ 66%]
tests/unit/test_wechat_service.py::TestBindWechat::test_bind_wechat_success PASSED [ 75%]
tests/unit/test_wechat_service.py::TestBindWechat::test_bind_wechat_already_bound PASSED [ 83%]
tests/unit/test_wechat_service.py::TestUnbindWechat::test_unbind_wechat_success PASSED [ 91%]
tests/unit/test_wechat_service.py::TestUnbindWechat::test_unbind_wechat_user_not_found PASSED [100%]

============================== 12 passed in 0.22s ===============================

结果: 12/12 测试通过

测试技术要点

1. Mock 策略

数据库会话 Mock

@pytest.fixture
def mock_session():
    session = AsyncMock()
    session.begin = MagicMock()
    session.begin.return_value.__aenter__ = AsyncMock()
    session.begin.return_value.__aexit__ = AsyncMock()
    return session

Redis Mock

@pytest.fixture
def mock_redis():
    redis = AsyncMock()
    return redis

ThreadPoolExecutor Mock

@pytest.fixture
def mock_executor():
    from concurrent.futures import ThreadPoolExecutor, Future
    executor = MagicMock(spec=ThreadPoolExecutor)
    
    def mock_submit(fn, *args, **kwargs):
        future = Future()
        try:
            result = fn(*args, **kwargs)
            future.set_result(result)
        except Exception as e:
            future.set_exception(e)
        return future
    
    executor.submit = mock_submit
    return executor

2. 异步测试

所有测试使用 @pytest.mark.asyncio 装饰器:

@pytest.mark.asyncio
async def test_generate_qrcode_mp_platform(self, wechat_service, mock_redis):
    # 测试逻辑
    pass

3. Patch 策略

使用 patch.object 模拟同步方法:

with patch.object(wechat_service, '_fetch_wechat_user_info', return_value=mock_user_info):
    result = await wechat_service.bind_wechat(user_id, 'test_code', 'mp')

4. 异常测试

使用 pytest.raises 验证异常:

with pytest.raises(ValidationError, match="无效的平台类型"):
    await wechat_service.generate_qrcode(platform='invalid')

修复的问题

1. DatabaseError 异常缺失

问题: app.core.exceptions 缺少 DatabaseError 异常类

修复: 添加 DatabaseError 异常类

class DatabaseError(Exception):
    """数据库操作异常"""
    pass

文件: server/app/core/exceptions.py

2. ThreadPoolExecutor Mock

问题: 简单的 MagicMock() 无法正确模拟 ThreadPoolExecutor

修复: 使用 concurrent.futures.Future 正确模拟 executor

测试覆盖率

功能覆盖

  • 生成二维码(公众号/开放平台)
  • 处理微信回调
  • 轮询登录结果
  • 新用户自动注册
  • 已存在用户登录
  • 绑定微信账号
  • 解绑微信账号
  • 异常处理(无效平台、用户不存在、已绑定等)

边界情况

  • 无效平台类型
  • 微信已被其他用户绑定
  • 用户不存在
  • 等待中状态

后续任务

  1. 集成测试执行:

    • 需要配置测试环境(Redis、数据库)
    • 需要 mock 微信 API 调用
    • 需要配置认证 fixture
  2. 测试覆盖率报告:

    docker exec jointo-server-app pytest tests/unit/test_wechat_service.py --cov=app.services.wechat_service --cov-report=html
    
  3. 端到端测试:

    • 完整的微信登录流程测试
    • 前端集成测试

参考文档

版本信息

  • 测试框架: pytest 7.4.4
  • 异步支持: pytest-asyncio 0.23.3
  • 实现日期: 2026-01-29
  • 测试状态: 12/12 通过