使用Pytest-asyncio测试FastAPI时执行ORM请求触发AttributeError
问题分析与解决方案
针对你在Pytest-asyncio测试FastAPI接口时,执行ORM请求出现AttributeError的问题,结合代码给出以下排查方向和修复方案:
1. 会话作用域不匹配导致依赖注入失败
你的db fixture默认是function作用域,而ac fixture是session作用域。当session级别的客户端调用function级别的数据库会话时,会引发依赖注入异常,导致db对象不符合预期,触发AttributeError。
修复:
将db fixture的作用域改为session,保持和ac一致:
@pytest.fixture(scope='session') async def db(): async with async_session_maker() as session: yield session
2. Menu模型导入或定义错误
如果测试文件中未正确导入Menu模型,或者模型未遵循SQLAlchemy异步规范定义,调用db.get()时会因找不到模型属性报错。
修复:
- 确保测试文件正确导入模型:
from your_app.models import Menu # 替换为实际模型路径 - 检查模型定义是否符合异步要求:
from sqlalchemy.ext.asyncio import AsyncAttrs from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column class Base(AsyncAttrs, DeclarativeBase): pass class Menu(Base): __tablename__ = "menus" id: Mapped[int] = mapped_column(primary_key=True) name: Mapped[str] # 其他字段定义...
3. 依赖覆盖逻辑错误
代码中app.dependency_overrides[db] = db的写法存在问题,这里的db如果直接引用fixture对象,无法正确替换FastAPI原有的数据库依赖。
修复:
定义专门的覆盖函数,替换原FastAPI中的数据库依赖:
# 假设原FastAPI依赖函数为get_db async def override_get_db(): async with async_session_maker() as session: yield session app.dependency_overrides[get_db] = override_get_db
4. 测试数据未正确初始化
id_dict['menu_id']如果未提前赋值或不存在,会导致db.get()传入无效参数,间接引发异常。
修复:
在测试中先创建测试数据,再使用有效ID查询:
@pytest.mark.asyncio async def test_get_menu(ac: AsyncClient, db): # 创建测试菜单 test_menu = Menu(name="测试菜单") db.add(test_menu) await db.commit() await db.refresh(test_menu) # 执行ORM查询 menu = await db.get(Menu, test_menu.id) assert menu is not None # 验证接口返回 response = await ac.get(f"/menus/{test_menu.id}") assert response.status_code == 200 assert response.json()["name"] == "测试菜单"
内容的提问来源于stack exchange,提问作者Kadim4
相关产品推荐
相关产品推荐

