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

FastAPI路由实例化时Mock字典失效的测试问题求助

问题根源

问题出在模块导入的时机:当你从main导入app时,main模块已经执行完毕——big_dictionary已加载,KeyName枚举也已经用原始字典生成完成。@patch是在测试函数运行时才替换main.big_dictionary,但此时枚举早已定型,根本不会使用新字典重新生成。

解决办法

方案1:重构代码,延迟应用初始化(推荐)

把枚举和FastAPI实例的创建封装成函数,这样可以在Mock生效后重新初始化应用,确保枚举使用Mock后的字典生成。

修改main.py:

from enum import Enum
from fastapi import FastAPI
from long_list import big_dictionary

def create_app():
    # 在函数内创建枚举,确保每次调用都用当前的big_dictionary生成
    KeyName = Enum('KeyName', names=[key for key in big_dictionary])
    app = FastAPI()

    @app.get("/")
    async def root(key_name: KeyName):
        return key_name
    return app

# 保留原有的app导出,不影响正常运行
app = create_app()

对应的测试用例:

from fastapi.testclient import TestClient
from unittest.mock import patch
from main import create_app

@patch('main.big_dictionary', {'test_entry3': 'value3', 'test_entry4': 'value4'})
def test_root(self):
    # 在Mock生效后创建app,此时枚举会用Mock的字典生成
    app = create_app()
    client = TestClient(app)
    response = client.get('/', params={"key_name": "TEST_ENTRY3"})
    self.assertEqual(response.status_code, 200)
    self.assertEqual(response.json(), "TEST_ENTRY3")

方案2:测试时重新加载模块

如果不想修改业务代码,可以在Mock生效后重新加载main模块,让它用新的字典重新生成枚举和应用。

测试用例代码:

from fastapi.testclient import TestClient
from unittest.mock import patch
import importlib
import main

def test_root(self):
    with patch('main.big_dictionary', {'test_entry3': 'value3', 'test_entry4': 'value4'}):
        # 重新加载main模块,触发模块内代码重新执行
        importlib.reload(main)
        client = TestClient(main.app)
        response = client.get('/', params={"key_name": "TEST_ENTRY3"})
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.json(), "TEST_ENTRY3")

方案3:直接修改枚举成员(临时hack)

如果既不想改业务代码,也不想重新加载模块,可以直接修改KeyName枚举的成员,测试后再恢复。

测试用例代码:

from fastapi.testclient import TestClient
from unittest.mock import patch
from main import app, KeyName

def test_root(self):
    # 保存原始枚举成员,测试后恢复
    original_members = KeyName.__members__.copy()
    # 添加Mock需要的枚举值
    KeyName.__members__.update({
        'TEST_ENTRY3': KeyName('TEST_ENTRY3', 3),
        'TEST_ENTRY4': KeyName('TEST_ENTRY4', 4)
    })
    try:
        client = TestClient(app)
        response = client.get('/', params={"key_name": "TEST_ENTRY3"})
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.json(), "TEST_ENTRY3")
    finally:
        # 恢复原始枚举结构
        KeyName.__members__.clear()
        KeyName.__members__.update(original_members)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 11:02:31