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

如何正确Mock FastAPI端点处理器内的函数?

FastAPI端点函数Mock失效问题解决

问题描述

在测试FastAPI接收文件的端点时,需要Mock封装了S3上传逻辑的s3_upload函数,但使用TestClient调用端点时Mock始终不生效,程序仍会尝试真实上传S3。直接调用处理器函数时Mock正常,推测和FastAPI调用机制有关。

相关代码示例:

# a_module/s3_upload.py
def s3_upload(bucket, filename, file):
    client = boto3.client('s3')
    client.put_object(Bucket="a-bucket", Key=filename, body=file)
# endpoints/route_file.py
from a_module import s3_upload

@app.put("/")
def route_file(file, filename):
    check_valid_file()
    s3_upload()

@pytest.fixture
def client():
    yield TestClient(app)
# tests/test_routes.py
def test_route_file(client, mocker):
    test_file = <whatever>
    mocker.patch("endpoints.s3_upload")
    response = client.put("/", file=test_file)

核心原因与解决办法

问题根源是Mock路径错误,Python的unittest.mock(包括pytest-mocker)遵循"where it's used"原则:必须patch函数被实际调用的模块中的引用,而非函数定义的模块路径。

在route_file.py中,你通过from a_module import s3_upload将函数导入到了endpoints.route_file模块的命名空间下,端点函数调用的是这个本地引用。而你当前patch的endpoints.s3_upload是错误路径(该路径不存在)。

修正步骤:

  • 把patch路径改为endpoints.route_file.s3_upload
  • 可选:添加Mock调用验证,确保Mock生效

修正后的测试代码:

# tests/test_routes.py
def test_route_file(client, mocker):
    test_file = <whatever>
    # 修正patch路径为函数被调用的模块路径
    mock_upload = mocker.patch("endpoints.route_file.s3_upload")
    response = client.put("/", file=test_file)
    
    # 验证Mock是否被正确调用
    mock_upload.assert_called_once()

额外说明:如果你的端点函数是通过import a_module然后调用a_module.s3_upload(),那么需要patch的路径就是a_module.s3_upload,此时直接patch原模块的函数即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 18:52:28