Python mock method call parameter displays the last state of the list

I have a function that takes a list as a parameter. The function is called several times and every time some of the list values ​​are updated. The moral object that I use to capture call arguments always shows the last values ​​in the list for all call arguments. The following code shows the problem.

from mock import MagicMock

def multiple_calls_test():
    m = MagicMock()
    params = [0, 'some_fixed_value', 'some_fixed_value']
    for i in xrange(1,10):
        params[0] = i
        m(params)
    for args in m.call_args_list:
        print args[0][0]

multiple_calls_test()

And here is the result: Note that all calls have 9 as the first element of the list.

[9, 'some_fixed_value', 'some_fixed_value']
[9, 'some_fixed_value', 'some_fixed_value']
[9, 'some_fixed_value', 'some_fixed_value']
[9, 'some_fixed_value', 'some_fixed_value']
[9, 'some_fixed_value', 'some_fixed_value']
[9, 'some_fixed_value', 'some_fixed_value']
[9, 'some_fixed_value', 'some_fixed_value']
[9, 'some_fixed_value', 'some_fixed_value']
[9, 'some_fixed_value', 'some_fixed_value']

Is there a way to force the mock to make a copy of the list argument instead of referencing the actual list? Or is there any other way to assert the correct value for each method execution? Thank.

+4
1

, mock, , , , . , , , , :

import copy
from mock import MagicMock


class CopyArgsMagicMock(MagicMock):
    """
    Overrides MagicMock so that we store copies of arguments passed into calls to the
    mock object, instead of storing references to the original argument objects.
    """

    def _mock_call(_mock_self, *args, **kwargs):
        args_copy = copy.deepcopy(args)
        kwargs_copy = copy.deepcopy(kwargs)
        return super(CopyArgsMagicMock, self)._mock_call(*args_copy, **kwargs_copy)

( ) MagicMock CopyArgsMagicMock CopyArgsMagicMock, .

, , , , , .

+5

Source: https://habr.com/ru/post/1537799/


All Articles