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

在含异步测试的FastAPI项目中为AsyncIOMotorClient添加索引

解决方案

一、应用启动时正确创建索引

在FastAPI主文件中,利用框架提供的启动事件执行异步索引创建操作,该操作会在FastAPI管理的事件循环上下文里运行,不会出现循环错误:

from fastapi import FastAPI
from your_mongo_module import mongo_instance  # 替换为你的Mongo类所在模块路径

app = FastAPI()

# 注册启动事件,应用启动时自动执行
@app.on_event("startup")
async def init_mongo_indexes():
    await mongo_instance.create_indexes()

二、修复测试场景的事件循环与索引初始化问题

1. 调整测试的事件循环与Mongo初始化Fixture

修改conftest.py,添加会话级自动执行Fixture,在测试开始前完成索引创建,同时确保事件循环正确管理:

import asyncio
import pytest
from your_mongo_module import mongo_instance

@pytest.fixture(scope="session")
def event_loop():
    """创建会话级别的事件循环,避免测试间循环冲突"""
    loop = asyncio.get_event_loop_policy().new_event_loop()
    yield loop
    loop.close()

@pytest.fixture(scope="session", autouse=True)
async def setup_mongo_for_tests():
    """测试会话开始前自动创建索引,无需手动调用"""
    await mongo_instance.create_indexes()
    yield
    # 可选:测试结束后可添加Mongo资源清理逻辑

2. 确保测试客户端为异步Fixture

如果你的async_clientFixture未正确定义,补充如下:

import pytest_asyncio
from httpx import AsyncClient
from main import app  # 导入你的FastAPI应用实例

@pytest_asyncio.fixture(scope="function")
async def async_client():
    async with AsyncClient(app=app, base_url="http://testserver") as client:
        yield client

问题根源说明

  • 直接在模块级别或非异步上下文里await create_indexes():模块加载时没有活跃的事件循环,会触发循环未初始化或已关闭的错误。
  • FastAPI的启动事件和测试的异步Fixture:均在框架/测试工具管理的合法事件循环中执行异步操作,可避免循环冲突问题。

内容的提问来源于stack exchange,提问作者Hossein

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 10:24:56