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

FastAPI测试中无法覆写类类型依赖的问题

FastAPI依赖覆写失效:模块级变量未被替换的解决方案

你的问题根源在于模块加载时提前初始化了assistant变量,FastAPI的app.dependency_overrides仅对通过依赖注入系统(Depends装饰器声明的依赖)管理的对象生效。模块级的assistant = AssistantProvider.get_assistant('multi')在应用启动时就已执行,绑定了真实的MultiAssistant,后续的依赖覆写无法改变这个已初始化的变量引用。


方案1:将assistant改为FastAPI依赖项

修改路由文件,把assistant的获取逻辑纳入FastAPI依赖系统,让框架管理它的实例化:

# messages.py(修改后)
from fastapi import APIRouter, Depends
from modules.assistant.assistant import AssistantProvider
router = APIRouter(...) 

def get_assistant():
    return AssistantProvider.get_assistant('multi')

@router.post("/start")
async def start(data: InitialMessageBody, assistant = Depends(get_assistant)):
    agent_conversation = await assistant.initial_message(data.user)
    return agent_conversation

测试时直接覆写这个get_assistant依赖:

# test_my_test.py(修改后)
from main import app
from fastapi.testclient import TestClient
from routers.messages import get_assistant

client = TestClient(app)

class MockAssistant:
    @staticmethod
    async def initial_message(user: str):
        return "Whatever message"

def mock_get_assistant():
    return MockAssistant

app.dependency_overrides[get_assistant] = mock_get_assistant

def test_start():
    response = client.post('/messages/start', json={"user": "foo"})
    assert response.json() == "Whatever message"

方案2:直接打桩AssistantProvider.get_assistant方法

如果不想修改路由代码,可使用Python标准库的unittest.mock直接替换目标方法的返回值:

# test_my_test.py(使用mock.patch)
from main import app
from fastapi.testclient import TestClient
from unittest.mock import patch
from modules.assistant.assistant import AssistantProvider

client = TestClient(app)

class MockAssistant:
    @staticmethod
    async def initial_message(user: str):
        return "Whatever message"

def test_start():
    with patch.object(AssistantProvider, 'get_assistant') as mock_get:
        mock_get.return_value = MockAssistant
        response = client.post('/messages/start', json={"user": "foo"})
        assert response.json() == "Whatever message"

上下文管理器patch.object能确保打桩在路由处理前生效,且测试结束后自动恢复原方法。


原方法无效的核心原因

你之前尝试覆写AssistantProvider类,但模块级assistant变量在应用启动时就已通过原类的方法获取了实例。覆写类本身不会改变已存在的变量引用,只有让FastAPI依赖系统管理对象获取,或直接打桩目标方法,才能替换真实实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 08:52:46