FastAPI+Beanie运行pytest遇Collection未初始化错误,求测试初始化方案
解决FastAPI+Beanie测试中的CollectionWasNotInitialized错误
问题场景
使用FastAPI和Beanie编写pytest测试时,持续触发以下错误:
FAILED tests/test_main.py::test_create_todo - beanie.exceptions.CollectionWasNotInitialized
问题根源
- TestClient使用错误:
TestClient是同步客户端,无需用await调用请求方法,异步调用会破坏上下文逻辑。 - 数据库连接不匹配:测试fixture初始化了测试数据库,但直接复用的主应用
app实例,通过lifespan钩子连接的是默认生产数据库,导致路由中Beanie模型关联的集合未完成初始化。 - 异步fixture执行顺序:原autouse fixture的
yield位置错误,会导致数据库初始化未完成就进入测试流程。
修复方案
1. 调整测试代码逻辑
- 通过环境变量指定测试数据库,让应用初始化逻辑自动适配测试环境
- 移除
TestClient请求的await关键字 - 测试前完成数据库初始化,测试后可选清理测试库避免数据残留
修改后的测试代码
# tests/test_main.py import pytest from fastapi.testclient import TestClient from src.core.database import init_db from src.main import create_app import os import motor.motor_asyncio @pytest.fixture(autouse=True) async def setup_test_database(): # 设置测试环境变量,覆盖默认数据库配置 os.environ["MONGO_URI"] = "mongodb://root:example@localhost:27017" os.environ["MONGO_DB_NAME"] = "test_todoapp" # 初始化测试数据库 await init_db(os.environ["MONGO_URI"], os.environ["MONGO_DB_NAME"]) yield # 测试完成后删除测试数据库(可选,保证每次测试环境干净) client = motor.motor_asyncio.AsyncIOMotorClient(os.environ["MONGO_URI"]) client.drop_database(os.environ["MONGO_DB_NAME"]) @pytest.fixture def client(): # 创建测试专用的app实例,确保读取测试环境变量的数据库配置 app = create_app() return TestClient(app) def test_create_todo(client): data = {"title": "Todo 1", "description": "Description Todo 1"} response = client.post("/todos", json=data) assert response.status_code == 201
2. 核心验证点
- 测试用
app通过create_app()重新创建,会读取测试环境变量,调用lifespan钩子初始化测试数据库 - 移除
await后,TestClient以同步方式正常发送请求 - 可选的数据库清理步骤保证每次测试都基于全新环境
内容的提问来源于stack exchange,提问作者user9929836
相关产品推荐
相关产品推荐

