Can mock side_effect iterator be reset after exhausting it?

mock.reset_mock() will not be reset by the side effects iterator. Is there a way to do this without creating a 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 goal is to reuse the layout in subsequent tests, but I suspect that, as a generator, it cannot be restarted.

So (better late than never) after it was directed in the right direction, I looked in mock.py and found that side_effect is an iterator object (which cannot be reset after exhaustion):

 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 affect the side effect.

+5
source share
1 answer

As user2357112 comments, reassigning side_effect will solve your problem.

 >>> from mock import MagicMock >>> >>> lst = [1, 2] >>> mock = MagicMock(side_effect=lst) >>> mock(), mock() (1, 2) >>> mock.side_effect = lst # <------- >>> mock(), mock() (1, 2) 
+3
source

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


All Articles