The Python Oracle

Python mock multiple return values

--------------------------------------------------
Rise to the top 3% as a developer or hire one of them at Toptal: https://topt.al/25cXVn
--------------------------------------------------

Music by Eric Matyas
https://www.soundimage.org
Track title: Ocean Floor

--

Chapters
00:00 Python Mock Multiple Return Values
01:18 Accepted Answer Score 598
01:41 Answer 2 Score 20
02:06 Answer 3 Score 0
02:21 Thank you

--

Full question
https://stackoverflow.com/questions/2489...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #unittesting #mocking #pythonmock

#avk47



ACCEPTED ANSWER

Score 598


You can assign an iterable to side_effect, and the mock will return the next value in the sequence each time it is called:

>>> from unittest.mock import Mock
>>> m = Mock()
>>> m.side_effect = ['foo', 'bar', 'baz']
>>> m()
'foo'
>>> m()
'bar'
>>> m()
'baz'

Quoting the Mock() documentation:

If side_effect is an iterable then each call to the mock will return the next value from the iterable.




ANSWER 2

Score 20


for multiple return values, we can use side_effect during patch initializing also and pass iterable to it

sample.py

def hello_world():
    pass

test_sample.py

from unittest.mock import patch
from sample import hello_world

@patch('sample.hello_world', side_effect=[{'a': 1, 'b': 2}, {'a': 4, 'b': 5}])
def test_first_test(self, hello_world_patched):
    assert hello_world() == {'a': 1, 'b': 2}
    assert hello_world() == {'a': 4, 'b': 5}
    assert hello_world_patched.call_count == 2



ANSWER 3

Score 0


I think the simplest solution is using a combination of iter(), patch(), side_effect.

from unittest.mock import patch
from return_inputs import *

def test_something_that_has_2_inputs(self):
        input_list = ['Foo', 'Bar']
        inputs = iter(input_list)
        with patch("builtins.input", side_effect=inputs):
            name1, name2 = return_inputs()
        assert name1 == "Foo"
        assert name2 == 'Bar'