我正在编写单元测试,并希望检查具有函数对象的调用,如下所示:
call(u'mock', u'foobar', <function <lambda> at 0x1ea99b0>, 10)
如何检查call()是否具有我想要的所有参数,而不重现lambda?
编辑:我想澄清一下,我在这里使用mock
库:http://mock.readthedocs.org/en/latest/。我在上面显示的call
是对MagicMock
对象的调用,我想使用assert_has_calls
进行检查。
答案 0 :(得分:25)
我终于找到了如何做我想做的事。基本上,当使用assert_has_calls
时,我想要一个参数匹配,无论它是什么(因为我不能在每次测试期间重新创建lambda
)。
这样做的方法是使用mock.ANY
。
所以,在我的例子中,这可以匹配调用:
mocked_object.assert_has_calls([
call('mock', 'foobar', mock.ANY, 10)
])
答案 1 :(得分:10)
如果你想要比mock.ANY更多的粒度,你可以创建自己的验证器类,用于调用比较,如assert_has_calls,assert_called_once_with等。
class MockValidator(object):
def __init__(self, validator):
# validator is a function that takes a single argument and returns a bool.
self.validator = validator
def __eq__(self, other):
return bool(self.validator(other))
可以使用:
import mock
my_mock = mock.Mock()
my_mock('foo', 8)
# Raises AssertionError.
my_mock.assert_called_with('foo', MockValidator(lambda x: isinstance(x, str)))
# Does not raise AssertionError.
my_mock.assert_called_with('foo', MockValidator(lambda x: isinstance(x, int)))
答案 2 :(得分:2)
不确定如何构建call
,但如果它是某种args
:
# IN THE CASE WE'RE DOING call(*args)
if all([len(args) == 4,isinstance(args[0],str),
isinstance(args[1],str), hasattr(args[2],'__call__'),
isinstance(args[3],int)]):
# PASS
else:
# FAIL
如果你过分担心获得一个不是函数的可调用输入,并且觉得单元测试会无声地失败:
from types import FunctionType
isinstance(lambda x: x,FunctionType) # True