Last updated: Apr 11, 2024
Reading timeยท3 min

Set the side_effect attribute of the Mock object to a list containing the
values to mock multiple return values in a Python unit test.
When the side_effect attribute is set to an iterable, each call to the mock
returns the next value in the iterable.
from unittest.mock import Mock m = Mock() m.side_effect = ['bobby', 'hadz', 'com'] print(m()) # ๐๏ธ bobby print(m()) # ๐๏ธ hadz print(m()) # ๐๏ธ com

If you need to return multiple values from a Python Mock (e.g. a list), set the
return_value attribute to a list.
from unittest.mock import Mock m = Mock() m.return_value = ['bobby', 'hadz', 'com'] print(m()) # ๐๏ธ ['bobby', 'hadz', 'com'] print(m()) # ๐๏ธ ['bobby', 'hadz', 'com'] print(m()) # ๐๏ธ ['bobby', 'hadz', 'com']

We used the
unittest.mock.Mock()
class to create a new Mock object.
The side_effect attribute can be set to an iterable, a function to be called when the mock is called or an exception to be raised.
We set the side_effect attribute to a list containing 3 items we want to
return from the Mock().
from unittest.mock import Mock m = Mock() m.side_effect = ['bobby', 'hadz', 'com'] print(m()) # ๐๏ธ bobby print(m()) # ๐๏ธ hadz print(m()) # ๐๏ธ com
When side_effect is set to an iterable, each call to the Mock returns the
next value in the iterable.
You can also pass the return values list to the Mock class upon instantiation.
from unittest.mock import Mock # ๐๏ธ passing side_effect list upon instantiation m = Mock(side_effect=['bobby', 'hadz', 'com']) print(m()) # ๐๏ธ bobby print(m()) # ๐๏ธ hadz print(m()) # ๐๏ธ com
The code sample achieves the same result.
You can also supply the side_effect argument when instantiating the
MagicMock()
class.
from unittest.mock import MagicMock m = MagicMock(side_effect=['bobby', 'hadz', 'com']) print(m()) # ๐๏ธ bobby print(m()) # ๐๏ธ hadz print(m()) # ๐๏ธ com
The MagicMock class is a subclass of Mock with default implementations for
most magic methods.
When you use the MagicMock class, you don't have to configure the magic
methods yourself.
If you exhaust the iterator, a StopIteration error is raised.
from unittest.mock import Mock m = Mock() m.side_effect = ['bobby', 'hadz', 'com'] print(m()) # ๐๏ธ bobby print(m()) # ๐๏ธ hadz print(m()) # ๐๏ธ com # โ๏ธ StopIteration print(m())
You can use the itertools built-in module if you want to return a specific
value after the iterator has been exhausted instead of raising a StopIteration
error.
from unittest.mock import Mock import itertools m = Mock() m.side_effect = itertools.chain( ['bobby', 'hadz'], itertools.repeat('com') ) print(m()) # ๐๏ธ bobby print(m()) # ๐๏ธ hadz print(m()) # ๐๏ธ com print(m()) # ๐๏ธ com print(m()) # ๐๏ธ com print(m()) # ๐๏ธ com
Instead of raising a StopIteration error, we return the string "com" after
the iterator is exhausted.

You can also use the patch() function decorator to return multiple values from a Mock.
Suppose we have the following example.py file.
def greet(name): return f'hello {name}'
Here is an example of mocking the example.greet function with multiple return
values.
from unittest.mock import patch import example @patch('example.greet', side_effect=['hello Alice', 'hello Bobby', 'hello Carl']) def test_greet_function(greet_patched): assert example.greet('Alice') == 'hello Alice' assert example.greet('Bobby') == 'hello Bobby' assert example.greet('Carl') == 'hello Carl' print(greet_patched) print(greet_patched.called) assert greet_patched is example.greet assert greet_patched.called assert greet_patched.call_count == 3 test_greet_function()

We used the patch() function decorator to patch the greet function from the
example module.
The first argument the patch() function takes should be a string in the form
of package.module.functionName or package.module.ClassName.
The target must be importable from the environment in which you are calling
patch().
We passed the side_effect sequence of return values to the @patch()
function.
@patch('example.greet', side_effect=['hello Alice', 'hello Bobby', 'hello Carl'])
Calls to the example.greet() method will return the items from the sequence
one after the other.
@patch('example.greet', side_effect=['hello Alice', 'hello Bobby', 'hello Carl']) def test_greet_function(greet_patched): assert example.greet('Alice') == 'hello Alice' assert example.greet('Bobby') == 'hello Bobby' assert example.greet('Carl') == 'hello Carl'
The decorated function gets passed the mock object.
You can assert that the mock has been called, how many times it has been called, etc.
print(greet_patched) print(greet_patched.called) assert greet_patched is example.greet assert greet_patched.called assert greet_patched.call_count == 3
Here is an example of asserting that the mock was called with specific arguments.
from unittest.mock import patch import example @patch('example.greet', side_effect=['hello Alice', 'hello Bobby', 'hello Carl']) def test_greet_function(greet_patched): assert example.greet('Alice') == 'hello Alice' greet_patched.assert_called_with('Alice') assert example.greet('Bobby') == 'hello Bobby' greet_patched.assert_called_with('Bobby') assert example.greet('Carl') == 'hello Carl' greet_patched.assert_called_with('Carl') print(greet_patched) print(greet_patched.called) test_greet_function()

I've also written a detailed guide on how to assert that Mock was called with specific arguments.
You can learn more about the related topics by checking out the following tutorials: