[Python] Can a mock side_effect iterator be reset after it has been exhausted?

Discussão em 'Python' iniciado por Stack, Julho 16, 2025.

  1. Stack

    Stack Membro Participativo

    mock.reset_mock() will not reset a side effect iterator. Is there a way to do this without creating the mock again?

    >>> from mock import MagicMock
    >>> mock = MagicMock(side_effect = [1,2])
    >>> mock(), mock()
    (1, 2)
    >>> mock()

    Traceback (most recent call last):
    File "<pyshell#114>", line 1, in <module>
    mock()
    File "C:\Python27\Lib\site-packages\mock.py", line 955, in __call__
    return _mock_self._mock_call(*args, **kwargs)
    File "C:\Python27\Lib\site-packages\mock.py", line 1013, in _mock_call
    result = next(effect)
    StopIteration
    >>> mock.reset_mock()
    >>> mock()

    Traceback (most recent call last):
    ...
    StopIteration
    >>> mock = MagicMock(side_effect = [1,2])
    >>> mock(), mock()
    (1, 2)
    >>>


    The intent is to re-use the mock in subsequent tests but I suspect that, like a generator, it cannot be restarted.

    So (better late than never) after being pointed in the right direction I looked in mock.py and found that side_effect is an iterator object (which cannot be reset once exhausted):

    def __set_side_effect(self, value):
    value = _try_iter(value)
    ...

    def _try_iter(obj):
    ...
    try:
    return iter(obj)
    except TypeError:
    # XXXX backwards compatibility
    # but this will blow up on first call - so maybe we should fail early?
    return obj


    and def reset_mock() does not address the side efect.

    Continue reading...

Compartilhe esta Página