FastAPI测试/token接口遇AttributeError:State无pool属性问题求助
解决FastAPI测试中
AttributeError: 'State' object has no attribute 'pool'问题 问题根源
TestClient是同步客户端,默认不会执行FastAPI的异步lifespan上下文管理器,导致app.state.pool(数据库连接池)未被初始化,调用接口时访问该属性就会抛出错误。同时,你的接口逻辑依赖异步数据库操作,同步客户端也无法正确处理异步路由。
解决方案
方法一:使用httpx.AsyncClient配合pytest fixture触发lifespan
- 安装依赖:
pip install httpx pytest-asyncio
- 修改
test_login.py代码:
import pytest from httpx import AsyncClient from app.main import app @pytest.fixture(scope="module") async def async_client(): # 启动FastAPI的异步lifespan上下文,初始化连接池 async with app.lifespan_context(app): async with AsyncClient(app=app, base_url="http://testserver") as client: yield client async def test_login(async_client): user = {"username": "unit-test", "password": "unittest"} response = await async_client.post("/token", data=user) assert response.status_code == 200
- 运行测试:
pytest test_login.py -v
方法二:手动管理测试用数据库连接池
如果不想依赖lifespan,可以在测试fixture中手动创建和关闭连接池:
import pytest import aiomysql from httpx import AsyncClient from app.main import app, get_config @pytest.fixture(scope="module") async def test_db_pool(): config = get_config() # 创建测试用连接池 pool = await aiomysql.create_pool( host=config.APP_DB_HOST, port=config.APP_DB_PORT, user=config.APP_DB_USER, password=config.APP_DB_PASSWORD, db=config.APP_DB_DATABASE, ) app.state.pool = pool yield # 测试结束后关闭连接池,释放资源 pool.close() await pool.wait_closed() @pytest.fixture(scope="module") async def async_client(test_db_pool): async with AsyncClient(app=app, base_url="http://testserver") as client: yield client async def test_login(async_client): user = {"username": "unit-test", "password": "unittest"} response = await async_client.post("/token", data=user) assert response.status_code == 200
注意事项
- 建议使用测试专用数据库,避免测试操作污染生产环境数据。
- 确保
pytest-asyncio已安装,pytest才能正确识别异步测试用例。
内容的提问来源于stack exchange,提问作者Alan Lechevallier
相关产品推荐
相关产品推荐

