python - 使用 Python 请求和响应模拟文件下载

标签 python unit-testing python-requests

我有一些 python 代码可以使用 requests 从 URL 成功下载图像, 并将其保存到 /tmp/ 中。我想测试它是否做了它应该做的。我正在使用 responses测试 JSON 文件的获取,但我不确定如何模拟获取文件的行为。

我假设它类似于模拟标准响应,如下所示,但我想我不知道如何将 body 设置为文件...

@responses.activate
def test_download():
    responses.add(responses.GET, 'http://example.org/images/my_image.jpg',
              body='', status=200,
              content_type='image/jpeg')
    #...

更新:根据 Ashafix 的评论,我正在尝试这个(python 3):

from io import BytesIO

@responses.activate
def test_download():
    with open('tests/images/tester.jpg', 'rb') as img1:
        imgIO = BytesIO(img1.read())

    responses.add(responses.GET, 'http://example.org/images/my_image.jpg',
              body=imgIO, status=200,
              content_type='image/jpeg')
    imgIO.seek(0)
    #...

但随后,当我正在测试的代码尝试执行我收到的请求时:

a bytes-like object is required, not '_io.BytesIO'

感觉差不多是对的,但是我被难住了。

更新 2:尝试遵循 Steve Jessop 的建议:

@responses.activate
def test_download():
    with open('tests/images/tester.jpg', 'rb') as img1:
        responses.add(responses.GET, 'http://example.org/images/my_image.jpg',
                  body=img1.read(), status=200,
                  content_type='image/jpeg')
        #...

但是这次被测试的代码引发了这个问题:

I/O operation on closed file.

当然图像应该仍然在 with block 中打开吗?

更新 3: 我正在测试的代码是这样的:

r = requests.get(url, stream=True)
if r.status_code == 200:
     with open('/tmp/temp.jpg', 'wb') as f:
        r.raw.decode_content = True
        shutil.copyfileobj(r.raw, f)

似乎是最后的 shutil 行正在生成“对已关闭文件的 I/O 操作”。错误。我不太了解这一点 - 文件的流式传输 - 不知道如何最好地模拟这种行为,测试下载的文件是否保存到 /tmp/

最佳答案

您可能需要将 stream=True 传递给 responses.add 调用。像这样的东西:

@responses.activate
def test_download():
    with open("tests/images/tester.jpg", "rb") as img1:
        responses.add(
            responses.GET,
            "http://example.org/images/my_image.jpg",
            body=img1.read(),
            status=200,
            content_type="image/jpeg",
            stream=True,
        )

关于python - 使用 Python 请求和响应模拟文件下载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37280960/

相关文章:

python - 根据日期标准合并 Pandas 中的列

运行脚本时 Python 属性错误 : type object 'BaseCommand' has no attribute 'option_list'

android - 使用 Android 测试过滤器(@SmallTest、@MediumTest、@LargeTest)进行本地单元测试

c# - 单元测试 Web Api Controller 假 ApiController。具有自定义身份的用户不起作用

python - 使用 Beautiful Soup 和 Python 抓取 Asp.NET 网站

javascript - 在浏览器中显示本地 gstreamer 流

python - 来自单独数组中纬度/经度坐标的(纬度,经度)的所有可能点

python - 使用 python requests 库网站总是挂起

javascript - 使用 $httpBackend 接收二进制响应的单元测试

Python从网页解析表格