【发布时间】:2017-01-22 17:07:21
【问题描述】:
我正在使用带有 Mock 的 Python 2.7。我有一个方法可以获取一个 url 并将其下载到一个临时文件中,然后根据业务逻辑规则重命名文件。我想测试这个重命名逻辑,但首先我必须模拟文件下载部分。这就是我卡住的地方。我在无限循环中使用urllib2.urlopen 及其read(chunkSize) 方法,检查read(chunkSize) 是否返回一些值。虽然这种方法在现实生活中有效,并且响应最终会被读取到 read(chunkSize) 不返回任何内容的末尾,但在模拟时我会得到一个无限循环。 read(chunkSize) 似乎总是有结果。读取响应内容后,如何让循环停止?这是我的代码:
import urllib2
from contextlib import closing
import unittest
import mock
def Method(url, temppath):
chunkSize = 16 * 1024
request = urllib2.Request(url)
with closing(urllib2.urlopen(request, timeout = 5)) as response:
with open(temppath, 'wb') as largeFile:
while True:
chunk = response.read(chunkSize)
# print chunk # <- this will endlessly produce '0123456' when tested by test_Method in MyTestCase
if not chunk:
break
largeFile.write(chunk)
# rename file from temppath to something new
class MyTestCase(unittest.TestCase):
@mock.patch('urllib2.urlopen', autospec=True)
@mock.patch('__main__.open', create=True)
def test_Method(self, mock_open, mock_urlopen):
mock_urlopen.return_value.read.return_value = b'0123456'
Method('http://a.bcd/img.png', 'a:\\b\\1234567890.tmp')
if __name__ == '__main__':
unittest.main()
【问题讨论】:
-
您在问题中描述了两个不同的功能(下载和重命名);那么为什么您认为将这 两个 填充到一个方法中是合适的呢?换句话说:当您首先可以下载和单独的重命名方法时,将重命名部分的测试难度提高 5 倍有什么意义?那么你在测试重命名部分时就不需要模拟任何下载了!
-
@GhostCat 主要是因为我需要一种将文件下载到临时位置,根据规则重命名并返回结果文件名的方法。事实上,我确实有一个单独的方法来重命名文件,但我仍然需要一个调用下载和重命名方法的函数。
标签: python python-2.7 unit-testing download mocking