如何模拟文件服务器中的文件存在来测试 FastAPI 静态文件?

问题描述 投票:0回答:1

我正在使用 FastAPI 静态文件类从服务器下载文件。一切正常,我可以使用 URL 轻松下载文件。

现在,我需要编写一个用于文件下载的测试用例,并且我不想仅仅为了测试目的而上传文件。我想模拟文件存在,所以我可以确保响应状态为 200。

但是,即使我模拟文件存在,我总是收到 404。你能帮我解决这个问题吗?

以下是 StaticFiles 在我的测试环境中的配置方式:

app_v1.mount("/files", StaticFiles(directory="server/api/v1/files"), name="files")

这是我的模拟测试用例:

def test_file_download(files_client: TestClient):
    mock_file_path = "server/api/v1/files/mocked_file.png"

    with patch('os.path.exists', return_value=True) as mock_exists:
        # Perform the GET request to download the file
        response_d = files_client.get("/files/mocked_file.png")  # Adjusted path

        # Validate the response
        assert response_d.status_code == 200
        assert mock_exists.called_once_with(mock_file_path)

请注意,如果我删除模拟并将文件物理放置到文件夹“server/api/v1/files/mocked_file.png”中,响应状态为 200。

另外,如果我评论断言response_d.status_code == 200,则测试运行成功,这表明调用了mock_exists. Called_once_with(mock_file_path)。然而不知何故,Staticfiles 仍然响应 404。

python mocking fastapi static-files
1个回答
0
投票

首先,我相信

StaticFiles
应用程序实际上并不使用
os.path.exists
来检查文件是否存在,因为它需要打开它才能提供下载服务。它可能试图直接打开它,这就是它认为它不存在的方式。

另一件事是,您也不应该假设它实际上使用

os
模块。首先,应该检查这一点,并且它也可以在新版本中更改。

您需要实际模拟

StaticFiles
调用自身的所有系统调用,这将非常复杂,而且这样做没有任何意义。更好的方法是为测试范围创建静态文件。

我会简单地创建一个包含一些内容的文件,并在测试结束后将其删除。有一个名为

tempfile
的标准 Python 模块,但该模块在
/tmp
中写入临时文件,因此您对文件的绝对路径的控制有限。对于这个简单的测试用例,我认为简单地创建和删除要测试的文件会更容易。

为了使其更安全(例如,如果测试因异常退出,它可能会跳过临时文件的清理),我会创建一个小型临时文件管理器。

import os


class MyTemporaryFile:
    def __init__(self, path: str, content: bytes):
        self.path = path
        self.content = content

    def __enter__(self):
        self.file = open(self.path, 'wb')
        self.file.write(self.content)
        self.file.close()
        return self.path

    def __exit__(self):
        os.unlink(self.path)

并在您的测试中使用它:

def test_foo():
    with MyTemporaryFile('/path/to/file', b'some test content') as filename:
        # test your code

这将自动创建包含您传递的内容的文件,并确保在

with
语句完成后删除该文件,即使内部存在错误。

© www.soinside.com 2019 - 2024. All rights reserved.