[英]Is it possible to query a Python mock object for the return values of its calls?
[英]Python mock library: Is there any way to get corresponding return values from magic mock calls?
在使用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
似乎是返回新的 sub-mock 对象的一种方便的方法,但也保留了call_args_list
。 但是, MagicMock
似乎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
,这就是没有它的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。 也就是说,如果你得到
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'
wraps参数呢?
class MyClass:
def foo(self, x):
return(x * x)
那么你可以像这样断言一个调用:
my_obj = MyClass()
with patch.object(MyClass, 'foo', wraps=MyClass().foo) as mocked_foo:
my_result = my_obj.foo(4)
mocked_foo.assert_called_with(4)
而 my_result 将包含调用 foo() 的实际结果
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.