pytest-mock
pytest-mock is a pytest plugin that provides a `mocker` fixture, acting as a thin wrapper around Python's `unittest.mock` library. It simplifies the process of creating and managing mock objects in pytest tests by automatically cleaning up mocks after each test. The library is actively maintained, with frequent updates to support new Python and pytest versions, currently at version 3.15.1.
Warnings
- breaking Support for older Python versions is frequently dropped. Python 3.8 support was dropped in v3.15.0, Python 3.7 in v3.12.0, and Python 3.5 in v3.6.0.
- breaking When using `mocker.spy` on functions that return iterators (e.g., `itertools._tee` objects), you now must explicitly pass `duplicate_iterators=True` to avoid `AttributeError` when accessing `spy_return` or `spy_return_iter`.
- breaking pytest-mock now requires `pytest>=6.2.5`. Older pytest versions will cause installation or runtime issues.
- breaking The `setup.py` file was removed. Projects relying on `setup.py install` or similar direct invocations will need to update their build process to use standard `pip install` or `pyproject.toml` based builds.
- gotcha Prior to v3.14.0, `mocker.patch.object` could sometimes fail to be properly cleared between tests, leading to unexpected test interactions or failures.
- gotcha While `unittest.mock` supports decorators and context managers for patching, `pytest-mock` prefers the `mocker` fixture. Using `mock.patch` as a decorator or context manager directly with `pytest-mock` may cause warnings or unexpected behavior, as the fixture handles cleanup automatically.
Install
-
pip install pytest-mock
Imports
- mocker
def test_example(mocker): ...
- MockType
from pytest_mock import MockType
- AsyncMockType
from pytest_mock import AsyncMockType
Quickstart
import os
class MyService:
def read_config(self, filename):
if not os.path.exists(filename):
return {}
with open(filename, 'r') as f:
return {'data': f.read()}
def test_read_config_file_exists(mocker):
mock_exists = mocker.patch('os.path.exists', return_value=True)
mock_open = mocker.patch('builtins.open', mocker.mock_open(read_data='key: value'))
service = MyService()
result = service.read_config('config.txt')
mock_exists.assert_called_once_with('config.txt')
mock_open.assert_called_once_with('config.txt', 'r')
assert result == {'data': 'key: value'}
def test_read_config_file_not_exists(mocker):
mocker.patch('os.path.exists', return_value=False)
mocker.patch('builtins.open', side_effect=FileNotFoundError)
service = MyService()
result = service.read_config('non_existent.txt')
assert result == {}