使用python 3.5.3 我想断言,模拟函数接收了特定的参数,但是我不想检查所有接收到的参数,仅检查对测试很重要的参数。
例如,而不是这样做:
my_func_mock.assert_called_with('arg1','arg2','arg3')
我想做类似的事情:
my_func_mock.assert_called_with_partial(arg2='arg2')
有可能吗?
答案 0 :(得分:4)
assert_called_with
检查最后一次调用的方式。在 MagicMock 对象中,可以在其 call_args.args
属性中找到最后一次调用的参数。最后一个调用的 kwargs 可以在它的 call_args.kwargs
属性中找到。我们可以单独检查这些。
假设在测试中我们调用了 my_func_mock
my_func_mock(arg0, arg1, kwarg1 = 'kw1', kwarg2 = 'kw2')
我们可以通过
直接检查单个参数assert my_func_mock.call_args.args[0] == arg0
assert my_func_mock.call_args.args[1] == arg1
对于任何 kwargs,我们可以通过
直接单独检查它们assert my_func_mock.call_args.kwargs['kwarg1'] == 'kw1'
assert my_func_mock.call_args.kwargs['kwarg2'] == 'kw2'
答案 1 :(得分:1)
您可以复制mock.NonCallableMock.assert_called_with
中的source并对其进行修改,以便可以实施以下与预期参数和关键字参数部分匹配的assert_called_with_partial
:
from unittest import mock
def assert_called_with_partial(_mock_self, *args, **kwargs):
self = _mock_self
if self.call_args is None:
expected = self._format_mock_call_signature(args, kwargs)
raise AssertionError('Expected call: %s\nNot called' % (expected,))
def _error_message():
msg = self._format_mock_failure_message(args, kwargs)
return msg
expected = self._call_matcher((args, kwargs))
expected_args, expected_kwargs = expected
actual_args, actual_kwargs = self._call_matcher(self.call_args)
if actual_args[:len(expected_args)] != expected_args or not (expected_kwargs.items() <= actual_kwargs.items()):
cause = expected if isinstance(expected, Exception) else None
raise AssertionError(_error_message()) from cause
mock.NonCallableMock.assert_called_with_partial = assert_called_with_partial
这样:
m = mock.MagicMock()
m(1, 2, a=1, b=2)
m.assert_called_with_partial(1, a=1)
不会引发AssertionError
,但是:
m.assert_called_with_partial(1, 2, a=2)
将提高
AssertionError: Expected call: mock(1, 2, a=2)
Actual call: mock(1, 2, a=1, b=2)
答案 2 :(得分:1)
您可以使用 unittest.mock 中的 ANY
。
from unittest.mock import MagicMock, ANY
my_func_mock = MagicMock()
my_func_mock('argument', 1, foo='keyword argument', bar={'a thing': 2})
my_func_mock.assert_called_once_with(
'argument',
1,
foo='keyword argument',
bar=ANY
)
这需要已经知道参数名称,但允许该参数的任何值。
见:https://docs.python.org/3/library/unittest.mock.html#unittest.mock.ANY