unittest.mock module
Overview
unittest.mock provides tools for replacing real objects in your tests with mock objects that you control. Mock a database, an HTTP client, or a filesystem call — you decide what the mock returns, and you can then assert that it was called with the arguments you expect.
Mocking is essential for testing code that depends on external services. You want fast, isolated tests that verify your code’s behavior without anything actually hitting the network or the disk.
unittest.mock is part of the standard library in Python 3.3+. A backport for older Python versions is available on PyPI as mock.
Mock Objects
The Mock class
Mock creates objects that record how they were used. Any attribute or method you access is created automatically and stored for later inspection:
from unittest.mock import Mock
mock = Mock()
mock.method(1, 2, key='value')
mock.attribute
mock.method.called # => True
mock.method.call_count # => 1
mock.method.call_args # => call(1, 2, key='value')
mock.attribute # => returns a new Mock
Configuring return values
Set return_value to control what the mock returns when called:
api = Mock()
api.fetch_user.return_value = {'id': 1, 'name': 'Alice'}
result = api.fetch_user(42)
result # => {'id': 1, 'name': 'Alice'}
Specifying an interface with spec
Use spec to restrict the mock to the interface of a real class. Accessing undefined attributes raises AttributeError:
from unittest.mock import Mock
from collections import OrderedDict
mock = Mock(spec=OrderedDict)
mock.missing_method()
# => AttributeError: OrderedDict has no attribute 'missing_method'
MagicMock
MagicMock is a Mock subclass that pre-creates all magic methods. Use it when you need to mock objects that implement __str__, __len__, __iter__, or other dunder methods:
from unittest.mock import MagicMock
mock = MagicMock()
mock.__str__.return_value = 'custom string'
str(mock) # => 'custom string'
mock['key'] # => returns a MagicMock
If you do not need magic methods, Mock is sufficient.
patch()
patch() replaces an attribute in a module or class for the duration of a test. It is the most common entry point for mocking in unit tests.
As a decorator
from unittest.mock import patch
import mymodule
@patch('mymodule.Database')
def test_save(MockDatabase):
MockDatabase.return_value.query.return_value = [{'id': 1}]
result = mymodule.get_data()
MockDatabase.assert_called_once()
assert result == [{'id': 1}]
The mock is passed as an argument to the decorated function. With nested decorators, mocks are passed bottom-up.
As a context manager
def test_save():
with patch('mymodule.Database') as MockDatabase:
MockDatabase.return_value.query.return_value = [{'id': 1}]
result = mymodule.get_data()
assert result == [{'id': 1}]
patch.object
patch.object patches a specific attribute on an object rather than in a module:
def test_timeout():
obj = SomeClass()
with patch.object(obj, 'timeout', 99):
assert obj.timeout == 99
patch.dict
patch.dict temporarily sets values in a dictionary:
from unittest.mock import patch
config = {'host': 'localhost', 'port': 5432}
with patch.dict(config, {'port': 9000}):
assert config['port'] == 9000
assert config['port'] == 5432 # restored
This is useful for mocking os.environ.
Side Effects
side_effect runs custom code when a mock is called, instead of returning a fixed value. It can be a function, an iterable, or an exception.
Raising exceptions
mock = Mock(side_effect=ValueError('something went wrong'))
mock() # raises ValueError
Returning different values per call
Pass a list to return a different value on each call:
mock = Mock(side_effect=[1, 2, 3])
mock() # => 1
mock() # => 2
mock() # => 3
Using a function as side effect
def fetch_remote(url):
if 'fail' in url:
raise ConnectionError('network error')
return {'status': 'ok'}
mock = Mock(side_effect=fetch_remote)
mock('http://example.com') # => {'status': 'ok'}
mock('http://fail.example.com') # raises ConnectionError
Assertions
Mock objects record every call automatically:
mock = Mock()
mock.process(1, 2, key='value')
mock.assert_called_once() # fails if called more than once
mock.assert_called_with(1, 2, key='value') # fails if args differ
mock.assert_not_called() # fails if called at all
Inspect call history:
mock.method.call_count # => 3
mock.method.call_args_list # => [call(1), call(2), call(3)]
create_autospec
create_autospec creates a mock that mirrors the call signature of the real function or class. Calling it with wrong arguments fails with the same TypeError as the real function:
from unittest.mock import create_autospec
from mymodule import some_function
mock_func = create_autospec(some_function, return_value='mocked')
mock_func(1, 2)
mock_func.assert_called_once_with(1, 2)
mock_func(1) # => TypeError: missing a required argument
Use autospec=True on patch() for the same effect as a decorator.
Common Use Cases
Mocking a database connection
@patch('mymodule.get_connection')
def test_query(MockConn):
mock_conn = Mock()
mock_conn.execute.return_value = [{'id': 1}]
MockConn.return_value = mock_conn
result = mymodule.run_query('SELECT * FROM users')
MockConn.assert_called_once_with()
mock_conn.execute.assert_called_once_with('SELECT * FROM users')
Mocking time
from unittest.mock import patch
with patch('time.sleep') as mock_sleep:
my_function_that_delays()
mock_sleep.assert_called_once_with(1)
Mocking environment variables
from unittest.mock import patch
with patch.dict('os.environ', {'API_KEY': 'test-secret'}):
result = load_config() # reads os.environ['API_KEY']
assert result.api_key == 'test-secret'
Gotchas
Patching at the wrong location. You must patch where the object is looked up, not where it is defined:
# WRONG — patches the local name inside mymodule
@patch('mymodule.SomeClass')
# CORRECT — patches where SomeClass is used
@patch('production_code.SomeClass')
Mock is too permissive by default. A Mock accepts any attribute access silently. Use spec to restrict it to the real interface:
# Without spec — silent failure
mock = Mock()
mock.nonexistent_method() # creates a new Mock, no error
# With spec — catches mistakes
mock = Mock(spec=RealClass)
mock.nonexistent_method() # => AttributeError
Forgetting cleanup. Using patch as a decorator or context manager handles cleanup automatically. Using Mock directly for monkey-patching requires manual teardown.
See Also
- /guides/unittest-guide/ — the unittest framework that integrates with
unittest.mock - /guides/mocking-with-pytest/ — mocking patterns when using pytest instead of unittest
- /guides/python-decorators/ — how
patchworks as a decorator