简体   繁体   English

python单元测试断言用部分调用

[英]python unit-test assert called with partial

using python 3.5.3 I want to assert that mocked function received specific arguments, but I don't want to check all received arguments, only the ones which are important for the test.使用 python 3.5.3 我想断言模拟函数收到了特定的参数,但我不想检查所有收到的参数,只检查对测试很重要的参数。

for example, instead of doing that:例如,而不是这样做:

my_func_mock.assert_called_with('arg1','arg2','arg3')

I would like to do something like:我想做类似的事情:

my_func_mock.assert_called_with_partial(arg2='arg2')

Is it possible?是否可以?

assert_called_with checks how the last call is made. assert_called_with检查最后一次调用是如何进行的。 In a MagicMock object, the last call's args can be found in its call_args.args attribute.在 MagicMock 对象中,可以在其call_args.args属性中找到最后一次调用的 args。 The last call's kwargs can be found in its call_args.kwargs attribute.最后一次调用的 kwargs 可以在其call_args.kwargs属性中找到。 We can check these individually.我们可以单独检查这些。

Say in a test we have called my_func_mock with假设在测试中我们调用了my_func_mock

my_func_mock(arg0, arg1, kwarg1 = 'kw1', kwarg2 = 'kw2')

We can directly check individual args by我们可以通过以下方式直接检查单个参数

assert my_func_mock.call_args.args[0] == arg0
assert my_func_mock.call_args.args[1] == arg1

and for any kwargs, we can directly check them individually by对于任何 kwargs,我们可以通过以下方式直接单独检查它们

assert my_func_mock.call_args.kwargs['kwarg1'] == 'kw1'
assert my_func_mock.call_args.kwargs['kwarg2'] == 'kw2'

You can copy the source of mock.NonCallableMock.assert_called_with and modify it so that you can implement the following assert_called_with_partial that partially matches the expected arguments and keyword arguments:您可以复制mock.NonCallableMock.assert_called_withmock.NonCallableMock.assert_called_with并对其进行修改,以便您可以实现以下部分匹配预期参数和关键字参数的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

so that:以便:

m = mock.MagicMock()
m(1, 2, a=1, b=2)
m.assert_called_with_partial(1, a=1)

will not raise an AssertionError , but:不会引发AssertionError ,但是:

m.assert_called_with_partial(1, 2, a=2)

will raise:将提高:

AssertionError: Expected call: mock(1, 2, a=2)
Actual call: mock(1, 2, a=1, b=2)

You can use ANY from unittest.mock.您可以使用 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
)

This requires knowing the argument names already but allows any value for that argument.这需要已经知道参数名称,但允许该参数的任何值。

See: https://docs.python.org/3/library/unittest.mock.html#unittest.mock.ANY请参阅: https : //docs.python.org/3/library/unittest.mock.html#unittest.mock.ANY

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM