FastAPI中dependency_overrides未覆盖数据库会话(pytest测试问题)
SQLModel + FastAPI 测试依赖未覆盖排查方案
核心排查项
依赖引用必须完全一致
测试文件中用于覆盖的get_session,必须和main.py接口依赖的是同一个函数实例。如果main.py是从database模块导入的get_session,测试里不能自行定义新的同名函数,必须直接导入该模块的get_session。Fixture执行顺序要正确
确保测试数据库会话的fixture先初始化,再创建覆盖依赖的FastAPI客户端。比如用pytest的yield控制顺序:先创建测试表、生成会话,再创建带依赖覆盖的TestClient,测试结束后清理表和会话。确认应用实例唯一性
测试中使用的app必须是main.py中定义的同一个FastAPI实例,不能在测试代码里重新创建新的FastAPI对象。数据库URL环境隔离
检查database模块是否根据测试环境切换到testing.db,比如通过环境变量区分:# database.py from sqlmodel import create_engine import os DATABASE_URL = "sqlite:///testing.db" if os.getenv("TESTING") == "1" else "sqlite:///production.db" engine = create_engine(DATABASE_URL, echo=True)依赖覆盖代码位置正确
必须在创建TestClient之前完成依赖覆盖,示例代码:# conftest.py import pytest from fastapi.testclient import TestClient from sqlmodel import Session, create_engine from main import app from database import get_session, SQLModelBase # 假设模型基类为SQLModelBase @pytest.fixture(name="session") def session_fixture(): engine = create_engine("sqlite:///testing.db", echo=True) SQLModelBase.metadata.create_all(engine) # 创建测试表 with Session(engine) as session: yield session SQLModelBase.metadata.drop_all(engine) # 清理测试表 @pytest.fixture(name="client") def client_fixture(session: Session): def override_get_session(): yield session app.dependency_overrides[get_session] = override_get_session yield TestClient(app) app.dependency_overrides.clear() # 测试后清除覆盖移除依赖的缓存装饰器
如果get_session被@lru_cache()等缓存装饰器修饰,会导致依赖无法被正确覆盖,测试环境下必须移除该装饰器。
常见错误点
- 忘记创建测试表:即使切换了数据库URL,未执行
metadata.create_all会导致测试库为空,但如果接口返回生产数据,说明根本没用到测试库。 - 依赖覆盖键错误:
app.dependency_overrides中使用的函数不是main里实际依赖的get_session实例。
内容的提问来源于stack exchange,提问作者Renato
相关产品推荐
相关产品推荐

