FastAPI+MongoDB pytest测试报NoneType无get_collection属性如何解决
问题原因
你遇到的报错核心是测试运行时MongoDB连接没有完成初始化,db.appDB 仍为None值,调用get_collection方法自然触发空指针异常。
具体触发原因:使用AsyncClient直接绑定FastAPI实例时,默认不会自动执行你注册的startup事件回调,导致connect_to_mongo函数没有被调用,数据库连接和appDB属性都没有完成赋值。而正常启动服务时uvicorn会自动触发startup事件,所以运行时不会报错。
解决方案
方案1:手动触发生命周期事件(快速修复)
直接在测试用例中手动执行数据库连接和关闭逻辑,修改测试代码如下:
import pytest from httpx import AsyncClient from fastapi import status from fastapi_project.main import app # 导入你定义的数据库连接/关闭函数 from fastapi_project.db import connect_to_mongo, close_mongo_connection @pytest.mark.asyncio async def test_successful_user_create(): # 测试前手动初始化数据库连接 await connect_to_mongo() async with AsyncClient(app=app, base_url="http://test") as ac: body = { 'username': 'test', 'email': 'test@test.com', 'hashed_password': 'password_test' } # 绑定app后无需写完整请求地址,直接写接口路径即可 res = await ac.post("/register", data=body) # 测试后手动关闭连接 await close_mongo_connection() assert res.status_code == status.HTTP_201_CREATED
方案2:封装pytest fixture(更规范,适合多测试用例场景)
如果有多个测试用例都需要用到数据库连接,可以封装为pytest fixture统一处理生命周期,避免每个用例重复写连接/关闭逻辑:
import pytest from httpx import AsyncClient from fastapi import status from fastapi_project.main import app from fastapi_project.db import connect_to_mongo, close_mongo_connection, db # fixture作用域可根据需求调整,function代表每个测试用例执行一次初始化/销毁 @pytest.fixture(scope="function") async def test_client(): # 测试前置:初始化数据库连接,建议测试环境单独使用测试库 await connect_to_mongo() async with AsyncClient(app=app, base_url="http://test") as client: yield client # 测试后置:清空测试数据+关闭连接,避免数据污染 await db.appDB.get_collection("users").delete_many({}) await close_mongo_connection() @pytest.mark.asyncio async def test_successful_user_create(test_client): body = { 'username': 'test', 'email': 'test@test.com', 'hashed_password': 'password_test' } res = await test_client.post("/register", data=body) assert res.status_code == status.HTTP_201_CREATED
额外注意项
- 建议为测试环境单独配置MongoDB数据库,不要和开发/生产环境混用,避免测试数据影响正常业务数据。
- 你粘贴的原始测试代码存在缩进错误:
async with AsyncClient行没有对应函数的缩进,若实际代码也是如此请先修正语法问题。 - 测试接口请求无需写完整的服务地址,绑定app后直接传接口路径即可,也不需要对应端口和服务实际运行。
内容的提问来源于stack exchange,提问作者Cristoff
相关产品推荐
相关产品推荐

