如何复用FastAPI的get_db函数作为pytest fixture?
复用FastAPI的get_db函数作为pytest fixture的方法
场景与问题
我在FastAPI项目中有一个用于提供数据库会话的辅助函数:
def get_db() -> Generator[Session, None, None]: try: db = SessionLocal() yield db finally: db.close()
尝试直接将它注册为pytest fixture时,写法如下但无法被识别:
pytest.fixture(get_db, name="db", scope="session") def test_item_create(db: Session) -> None: ...
运行测试时会抛出错误:fixture 'db' not found。我可以在conftest.py中重写该函数并包装为fixture,但希望找到更高效的复用方式,避免重复编写类似辅助函数。
正确的复用方式
方法1:通过高阶函数调用注册fixture
pytest.fixture()是一个高阶函数,需要先调用它生成装饰器,再用这个装饰器去包装你的get_db函数。推荐在conftest.py中完成注册(全局生效):
from your_fastapi_module import get_db import pytest from sqlalchemy.orm import Session # 先调用pytest.fixture配置参数,再用返回的装饰器包装get_db pytest.fixture(scope="function", name="db")(get_db)
也可以直接在测试文件中注册:
from your_module import get_db import pytest pytest.fixture(scope="function", name="db")(get_db) def test_item_create(db: Session): # 测试逻辑 pass
方法2:封装为新fixture调用原函数
如果需要对原函数的行为做微调(比如修改scope后的事务处理),可以在fixture中直接调用原get_db,避免重写完整逻辑:
from your_fastapi_module import get_db import pytest @pytest.fixture(scope="function", name="db") def fixture_db(): # 直接复用原get_db的生成器逻辑 yield from get_db()
原写法失败的原因
你之前的代码pytest.fixture(get_db, name="db", scope="session")参数传递错误:pytest.fixture的第一个参数是scope,而非目标函数。这种写法会把get_db当作scope参数传入,导致pytest没有正确将其注册为fixture,自然找不到名为db的fixture。
注意事项
- 关于
scope的选择:如果原get_db是创建新的数据库会话,建议使用scope="function",每个测试函数独立使用会话并在结束后关闭,避免测试间的数据污染;若确定会话可以共享,再用scope="session"。
内容的提问来源于stack exchange,提问作者kaveh
相关产品推荐
相关产品推荐

