使用Mock Python返回Iterable

Mat*_*att 18 python mocking

我正在尝试使用Mock来模拟python中的一个函数.这是我的代码:

    resp, content = request(...)
Run Code Online (Sandbox Code Playgroud)

request()函数需要返回两个值.这是我试过的:

    with patch("syncdatetime.py") as sync_mock:
        sync_mock.request.return_value = [obj, '']
Run Code Online (Sandbox Code Playgroud)

但是当我运行测试时,我得到错误"模拟对象不可迭代".请求函数返回Mock类型的对象而不是列表.如何修改请求函数以便返回列表?

小智 13

我怀疑你的问题是你没有使用你认为自己的模拟实例.默认情况下,Mock实例在调用时返回Mock.

>>> m = mock.Mock()
>>> type(m())
<class 'mock.mock.Mock'>    
Run Code Online (Sandbox Code Playgroud)

看起来你的调用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
Run Code Online (Sandbox Code Playgroud)

您不应该使用side_effect返回列表.分配return_value应该有效.

>>> m = mock.Mock()
>>> m.return_value = ['a', 'b']
>>> (a, b) = m()
>>> a
'a'
>>> b
'b'
Run Code Online (Sandbox Code Playgroud)


Dom*_*ugh 10

请注意披露,我是新来的模拟,所以我不是专家,但是,我刚遇到同样的问题,发现将side_effect属性设置为返回数组的函数修复了一些事情

从您的示例代码中,更改:

with patch("syncdatetime.py") as sync_mock:
    sync_mock.request.return_value = [obj, '']
Run Code Online (Sandbox Code Playgroud)

with patch("syncdatetime.py") as sync_mock:
    sync_mock.request.side_effect = function_returning_list
Run Code Online (Sandbox Code Playgroud)

并定义

def function_returning_list(arg_list_of_choice):
    #anything you want to do goes here
    #then
    return your_list
Run Code Online (Sandbox Code Playgroud)

  • 我没试过这个,但我确实找到了一个更简单的解决方案.修补函数本身,然后设置patch.return_value,而不是修补模块.老实说,我不完全确定为什么这样可行,但这样,函数不返回Mock对象.谢谢你的回应. (3认同)