You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI+Beanie运行pytest遇Collection未初始化错误,求测试初始化方案

解决FastAPI+Beanie测试中的CollectionWasNotInitialized错误

问题场景

使用FastAPI和Beanie编写pytest测试时,持续触发以下错误:

FAILED tests/test_main.py::test_create_todo - beanie.exceptions.CollectionWasNotInitialized

问题根源

  1. TestClient使用错误:TestClient是同步客户端,无需用await调用请求方法,异步调用会破坏上下文逻辑。
  2. 数据库连接不匹配:测试fixture初始化了测试数据库,但直接复用的主应用app实例,通过lifespan钩子连接的是默认生产数据库,导致路由中Beanie模型关联的集合未完成初始化。
  3. 异步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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 01:55:18