在使用mock
库编写Python测试时,我经常得到“调用方法的参数”,像这样,
from __future__ import print_function
import mock
m = mock.MagicMock(side_effect=lambda x: x * x)
m(4)
print("m called with: ", m.call_args_list)
(这将打印m called with: [call(4)]
)。问题:有没有办法获得返回值(在这种情况下,16
)?
详细信息:在我的特定场景中,我想使用side_effect返回一个子模拟对象:内省该对象以查看对其进行调用的内容非常重要。例如,“真实代码”(非测试代码)可能会写入,
myobj = m(4)
myobj.foo()
使用side_effect
似乎是一种方便的方式来返回新的子模拟对象,但也保持在call_args_list
周围。但是,它似乎不像MagicMock
存储从side_effect
函数返回值...我错了吗?
如果你问我,这不是嘲笑的目的。如果要断言返回值,则应直接调用该函数。如果你需要通过箍来注册函数返回的内容,那么你的设计很可能是有缺陷的。
例如,如果您有内部函数,则不应测试内部函数。如果要测试内部函数,请将其公开访问。
所以不是这样的:
def spam(input):
def eggs(nested):
return nested*2
input = eggs(nested)
return eggs(input)
做这个:
def eggs(nested):
return nested*2
def spam(input):
input = eggs(nested)
return eggs(input)
你不需要一个side_effect
,这就是没有它的嘲讽,它们会返回其他嘲笑。
你通过做mymock.return_value.assert_called_once_with(4)
对它们做出断言
如果你这样做了,你只需要返回一个模拟,你可以从side_effect
那里得到其他地方的引用。
使用return_value
。
例如,
import unittest
import mock
def foo(m):
myobj = m(4)
myobj.foo()
import unittest
class TestFoo(unittest.TestCase):
def test_foo(self):
m2 = mock.MagicMock()
m = mock.MagicMock(return_value=m2)
foo(m)
m.assert_called_once_with(4)
m2.foo.assert_called_once_with()
if __name__ == '__main__':
unittest.main()
你有一个call()对象。你想让args INSIDE调用对象。也就是说,如果你得到了
call_args_list[0] == call(3, 5)
你想要3和5. call()对象可以被索引 - 首先引用elem 0,这是实际参数的列表。然后,你想要3,它在其中作为第0个元素。
得到这个:
cargs = call_args_list[0]
assert cargs[0][0] == 3
>>> mockObjThing.someFunc.call_args_list[0]
call('argOne', 'argTwo')
>>> # DAGNABBIT I want argOne!!!
>>> cargs = mockObjThing.someFunc.call_args_list[0]
>>> cargs
call('argOne', 'argTwo')
>>> cargs[0]
('argOne', 'argTwo')
>>> cargs[0][0]
'argOne'