如何使用标准模拟库模拟 urllib2

How to mock urllib2 with standard mock library

我遇到了与 Mocking urllib2.urlopen().read() for different responses

类似的问题

但是这个解决方案对我不起作用。

当我想模拟 urlopen 对象时,我的模拟对象总是 return <MagicMock name='urlopen().read()' id='140016097869776'>

这是我要测试的,mod.py

import urllib2
from zipfile import ZipFile
from io import BytesIO
def verify(url, checksum):
    try:
        conn = urllib2.urlopen(url)
        byte = conn.read()
        conn.close()           
        myzip = ZipFile(BytesIO(byte))
    except Exception as e:
        err = get_error(400, "Not a valid zip format: %s" % (str(e)))
        return Response(err, status=status.HTTP_400_BAD_REQUEST)
    return byte

这是我的嘲讽

@mock.patch('mod.urllib2.urlopen')
@mock.patch('mod.ZipFile')
@mock.patch('mod.BytesIO')
def test_verify(self, urlopen_mock, zipfile_mock, bytesio_mock):
    conn = mock.Mock()
    conn.read.return_value = 'byte'
    urlopen_mock.return_value = conn
    zf = mock.Mock()
    zipfile_mock.return_value = zf
    assertEqual(verify('url','checksum'), 'byte')

但是,returned 字节总是 <MagicMock name='urlopen().read()' id='140016097869776'>,而不是我模拟的 'byte'

我错过了什么重要的事情吗?

您需要在 conn 的 return 值上定义 read

conn.return_value.read.return_value = 'byte'

编辑 我误诊了问题。实际问题是方法参数的传递顺序与装饰器的应用方式相反:所以你的签名应该是:

def test_verify(self, bytesio_mock, zipfile_mock, urlopen_mock):