Mock文件存在测试FastAPI Static Files下载时持续返回404如何解决?
解决FastAPI StaticFiles测试中Mock文件存在仍返回404的问题
你遇到的问题核心是:FastAPI依赖的Starlette StaticFiles组件,内部并非直接使用os.path.exists来检查文件,而是调用了其他文件系统校验方法,所以只Mockos.path.exists不会生效。
原因分析
Starlette的StaticFiles在处理请求时,会执行以下关键检查:
- 调用
starlette.staticfiles.isfile验证目标路径是文件(而非目录) - 调用
os.path.getsize获取文件大小(用于响应头) - 部分逻辑会用
os.stat获取文件元数据
你的Mock只覆盖了os.path.exists,但这些实际被调用的方法仍会返回真实结果(文件不存在),所以StaticFiles依然返回404。
可行的解决方案
方案1:Mock Starlette的文件检查方法
直接Mock StaticFiles内部使用的isfile和getsize方法,这是最直接的方式:
from starlette.staticfiles import isfile def test_file_download(files_client: TestClient): # Mock文件存在校验和文件大小获取 with patch('starlette.staticfiles.isfile', return_value=True), \ patch('starlette.staticfiles.os.path.getsize', return_value=1024): response_d = files_client.get("/files/mocked_file.png") assert response_d.status_code == 200
方案2:Mock底层的os.stat和os.path.isfile
如果需要更贴近底层的Mock,可以覆盖os.stat返回合法的文件元数据,同时Mockos.path.isfile:
def test_file_download(files_client: TestClient): mock_file_path = "server/api/v1/files/mocked_file.png" with patch('os.stat') as mock_stat, \ patch('os.path.isfile', return_value=True): # 构造合法的文件stat结果(0o100644表示普通文件权限) mock_stat.return_value = os.stat_result( (0o100644, 0, 0, 0, 0, 0, 1024, 0, 0, 0) ) response_d = files_client.get("/files/mocked_file.png") assert response_d.status_code == 200 mock_stat.assert_called_once_with(mock_file_path)
验证说明
- 两种方案都能让StaticFiles认为文件存在,返回200状态码
- 不需要创建真实文件,完全通过Mock完成测试
内容的提问来源于stack exchange,提问作者Aidos Kenessov
相关产品推荐
相关产品推荐

