返回带有模拟 Python 的可迭代对象

24

我正在尝试使用Mock来模拟Python中的函数。这是我的代码:

    resp, content = request(...)

request()函数需要返回两个值。这是我尝试的方法:

    with patch("syncdatetime.py") as sync_mock:
        sync_mock.request.return_value = [obj, '']

但是当我运行测试时,出现了错误“Mock object is not iterable.”。请求函数返回的是 Mock 类型的对象,而不是列表。我该如何修补请求函数以便它返回一个列表?

2个回答

19

我怀疑你的问题是你没有使用你所认为的模拟实例。默认情况下,调用Mock的实例会返回一个Mock。

>>> m = mock.Mock()
>>> type(m())
<class 'mock.mock.Mock'>    

看起来你调用request时返回了一个Mock对象,因为return_value没有被初始化,这意味着resp,content = request()试图解包一个Mock对象。

>>> m = mock.Mock()
>>> (a, b) = m()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'Mock' object is not iterable

你不应该使用side_effect来返回一个列表,直接给return_value赋值就可以了。

>>> m = mock.Mock()
>>> m.return_value = ['a', 'b']
>>> (a, b) = m()
>>> a
'a'
>>> b
'b'

12
披露一下,我对Mock还不是很熟练,但是我刚刚遇到了同样的问题,并发现将side_effect属性设置为返回数组的函数可以解决问题。
根据您的示例代码,更改如下:
with patch("syncdatetime.py") as sync_mock:
    sync_mock.request.return_value = [obj, '']

为了

with patch("syncdatetime.py") as sync_mock:
    sync_mock.request.side_effect = function_returning_list

并定义

def function_returning_list(arg_list_of_choice):
    #anything you want to do goes here
    #then
    return your_list

3
我没有尝试过这个方法,但我找到了一个更简单的解决方案。不要修补模块,而是修补函数本身,然后设置 patch.return_value。说实话,我不完全确定为什么这样可以,但这样做,函数就不会返回一个 Mock 对象。谢谢你的回复。 - Matt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接