django测试文件下载 - “ValueError:关闭文件的I / O操作”

时间:2013-10-14 11:43:27

标签: python django unit-testing

我有一个用于文件下载的视图的代码,它在浏览器中工作正常。现在我正在尝试使用内部django Client.get:

为它编写测试
    response = self.client.get("/compile-book/", {'id': book.id})
    self.assertEqual(response.status_code, 200)
    self.assertEquals(response.get('Content-Disposition'), 
                      "attachment; filename=book.zip")
到目前为止一切顺利。现在我想测试下载的文件是否是我希望它下载的文件。所以我先说:

    f = cStringIO.StringIO(response.content)

现在我的测试运行员回复:

Traceback (most recent call last):
  File ".../tests.py", line 154, in test_download
    f = cStringIO.StringIO(response.content)
  File "/home/epub/projects/epub-env/lib/python2.7/site-packages/django/http/response.py", line 282, in content
    self._consume_content()
  File "/home/epub/projects/epub-env/lib/python2.7/site-packages/django/http/response.py", line 278, in _consume_content
    self.content = b''.join(self.make_bytes(e) for e in self._container)   
  File "/home/epub/projects/epub-env/lib/python2.7/site-packages/django/http/response.py", line 278, in <genexpr>
    self.content = b''.join(self.make_bytes(e) for e in self._container)   
  File "/usr/lib/python2.7/wsgiref/util.py", line 30, in next 
    data = self.filelike.read(self.blksize) 
ValueError: I/O operation on closed file

即使我只是这样做:self.assertIsNotNone(response.content)我得到相同的ValueError

整个互联网上的主题(包括django文档)我可以找到关于测试下载的主题是这个stackoverflow主题:Django Unit Test for testing a file download。尝试该解决方案可以获得这些结果。对我来说,这是一个古老而罕见的问题。

有人知道如何在Django中处理下载测试吗? (顺便说一句,在python 2.7上运行django 1.5)

2 个答案:

答案 0 :(得分:3)

这对我们有用。我们返回rest_framework.response.Response但它也应该与常规的Django响应一起使用。

import io
response = self.client.get(download_url, {'id': archive_id})
downloaded_file = io.BytesIO(b"".join(response.streaming_content))

注意: streaming_content仅适用于StreamingHttpResponse(也是Django 1.10): https://docs.djangoproject.com/en/1.10/ref/request-response/#django.http.StreamingHttpResponse.streaming_content

答案 1 :(得分:1)

我有一些文件下载代码和一个与Django 1.4一起使用的相应测试。当我升级到Django 1.5时(与您遇到的ValueError: I/O operation on closed file错误相同),测试失败。

我通过更改非测试代码来修复它,使用StreamingHttpResponse代替标准HttpResponse。我的测试代码使用response.content,因此我首先迁移到CompatibleStreamingHttpResponse,然后将我的测试代码更改为使用response.streaming_content,以允许我放弃CompatibleStreamingHttpResponse以支持{{1} }}