Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 01bafdc

Browse files
committed
Issue 17826. Setting an iterable side_effect on a mock created by create_autospec now works
1 parent 061cb3b commit 01bafdc

3 files changed

Lines changed: 34 additions & 2 deletions

File tree

Lib/unittest/mock.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,14 @@ def _check_and_set_parent(parent, value, name, new_name):
343343
value._mock_name = name
344344
return True
345345

346-
346+
# Internal class to identify if we wrapped an iterator object or not.
347+
class _MockIter(object):
348+
def __init__(self, obj):
349+
self.obj = iter(obj)
350+
def __iter__(self):
351+
return self
352+
def __next__(self):
353+
return next(self.obj)
347354

348355
class Base(object):
349356
_mock_return_value = DEFAULT
@@ -495,7 +502,11 @@ def __get_side_effect(self):
495502
delegated = self._mock_delegate
496503
if delegated is None:
497504
return self._mock_side_effect
498-
return delegated.side_effect
505+
sf = delegated.side_effect
506+
if sf is not None and not callable(sf) and not isinstance(sf, _MockIter):
507+
sf = _MockIter(sf)
508+
delegated.side_effect = sf
509+
return sf
499510

500511
def __set_side_effect(self, value):
501512
value = _try_iter(value)

Lib/unittest/test/testmock/testmock.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,24 @@ def side_effect():
154154
mock = Mock(side_effect=side_effect, return_value=sentinel.RETURN)
155155
self.assertEqual(mock(), sentinel.RETURN)
156156

157+
def test_autospec_side_effect(self):
158+
# Test for issue17826
159+
results = [1, 2, 3]
160+
def effect():
161+
return results.pop()
162+
def f():
163+
pass
164+
165+
mock = create_autospec(f)
166+
mock.side_effect = [1, 2, 3]
167+
self.assertEqual([mock(), mock(), mock()], [1, 2, 3],
168+
"side effect not used correctly in create_autospec")
169+
# Test where side effect is a callable
170+
results = [1, 2, 3]
171+
mock = create_autospec(f)
172+
mock.side_effect = effect
173+
self.assertEqual([mock(), mock(), mock()], [3, 2, 1],
174+
"callable side effect not used correctly")
157175

158176
@unittest.skipUnless('java' in sys.platform,
159177
'This test only applies to Jython')

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ Core and Builtins
3333
Library
3434
-------
3535

36+
- Issue #17826: setting an iterable side_effect on a mock function created by
37+
create_autospec now works. Patch by Kushal Das.
38+
3639
- Issue #7776: Fix ``Host:`` header and reconnection when using
3740
http.client.HTTPConnection.set_tunnel(). Patch by Nikolaus Rath.
3841

0 commit comments

Comments
 (0)