""" conftest.py — 测试环境 stub 在任何模块 import 之前注入环境变量,让 Settings 校验通过。 只用于本地单元/集成测试,不影响生产。 """ import os import sys import types # ── 1. 注入最小可用配置(全假值,只让 Settings 构建通过)──────── _TEST_ENV = { "FERNET_KEY": "test-fernet-key-at-least-32-chars-long!!", "JWT_SECRET": "test-jwt-secret-at-least-32-chars-long!!", "DATABASE_URL": "mysql+pymysql://test:test@localhost/test", "MONGO_URI": "mongodb://localhost:27017/test", "REDIS_URL": "redis://localhost:6379/0", "APP_ENV": "test", } for k, v in _TEST_ENV.items(): os.environ.setdefault(k, v) # ── 2. 清掉 lru_cache,让 Settings 用刚注入的 env vars 重建 ───── from app.core import config as _cfg _cfg.get_settings.cache_clear() # ── 3. Stub motor(MongoDB client,本地没装)────────────────────── if "motor" not in sys.modules: motor_mod = types.ModuleType("motor") motor_async = types.ModuleType("motor.motor_asyncio") motor_async.AsyncIOMotorClient = object sys.modules["motor"] = motor_mod sys.modules["motor.motor_asyncio"] = motor_async # ── 4. Stub database engine(MySQL URL 但不连接)────────────────── # database.py 顶层调 create_engine,pytest 环境没有 MySQL。 # 只 stub engine 和 SessionLocal,不影响任何逻辑测试。 import unittest.mock as _mock import sqlalchemy _fake_engine = _mock.MagicMock() _fake_session_class = _mock.MagicMock() _fake_session_class.return_value.__enter__ = _mock.MagicMock(return_value=_mock.MagicMock()) _fake_session_class.return_value.__exit__ = _mock.MagicMock(return_value=False) # 只在 database 模块还未 import 时 patch;若已 import 则直接替换属性 if "app.core.database" not in sys.modules: with _mock.patch("sqlalchemy.create_engine", return_value=_fake_engine): with _mock.patch("sqlalchemy.orm.sessionmaker", return_value=_fake_session_class): import app.core.database as _db_mod else: _db_mod = sys.modules["app.core.database"] # 确保 engine/SessionLocal 是 mock,防止实际连接 _db_mod.engine = _fake_engine _db_mod.SessionLocal = _fake_session_class