我使用Python 2.7和Mock。我有一个方法,它接受一个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()
答案 0 :(得分:4)
指定值的列表以返回side_effect
attribute:
mock_urlopen.return_value.read.side_effect = [b'0123456', b'']
mock将遍历每个read()
调用的值,因此返回空字节对象的最后一个调用将终止循环。