pytest-mock

raw JSON →
3.15.1 verified Tue May 12 auth: no python install: stale quickstart: verified

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.

pip install pytest-mock
error NameError: name 'mocker' is not defined
cause The 'mocker' fixture is not recognized, usually because `pytest-mock` is not installed, or the test function is not accepting 'mocker' as an argument.
fix
Ensure pytest-mock is installed (pip install pytest-mock) and that your test function includes mocker in its signature (e.g., def test_something(mocker):).
error ModuleNotFoundError: No module named 'pytest_mock'
cause The `pytest-mock` library has not been installed in the Python environment where pytest is being run.
fix
Install the library using pip: pip install pytest-mock.
error AttributeError: module 'your_module' has no attribute 'some_function'
cause You are attempting to patch a function, class, or attribute at a location where it does not exist *at the time the code under test looks it up*. This often happens when patching the original definition instead of where it's imported and used within the module being tested.
fix
Identify the exact location (module path) where the object is *looked up* by the code you are testing and patch it there. For example, if my_module.py imports external_func from external_lib and calls it, you should patch my_module.external_func instead of external_lib.external_func.
error TypeError: 'MagicMock' object is not callable
cause This error occurs when you attempt to call a mock object that was not configured to be callable, or when you incorrectly call a mocked attribute that is not a function or method in the real object (especially with `autospec`), or when a mock's `return_value` is set to a non-callable object which is then erroneously called by the tested code.
fix
Ensure that the mock is configured to be callable if needed (e.g., by default, mocker.patch creates a callable mock). If mocking a property, use new_callable=mocker.PropertyMock. If the return_value of a mock is expected to be called, ensure it's set to a callable object or another mock.
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.
fix Ensure your project runs on a supported Python version (currently >=3.9 for v3.15.1).
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`.
fix For `mocker.spy` calls on iterators, update to `mocker.spy(obj, 'method', duplicate_iterators=True)`.
breaking pytest-mock now requires `pytest>=6.2.5`. Older pytest versions will cause installation or runtime issues.
fix Upgrade your pytest installation: `pip install --upgrade pytest`.
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.
fix Refer to the Python packaging documentation or project's `pyproject.toml` for modern installation methods. Avoid direct `python setup.py install`.
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.
fix Upgrade to `pytest-mock>=3.14.0` to ensure `mocker.patch.object` is correctly cleared. Manually call `mocker.stopall()` or ensure mocks are short-lived if upgrading is not an option.
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.
fix Always prefer `mocker.patch()`, `mocker.patch.object()`, etc., within your test functions rather than `unittest.mock` decorators or `with patch(...)` statements when using `pytest-mock`.
gotcha The system package manager `pip` issued warnings or notices during installation or environment setup, unrelated to pytest-mock's functionality. These typically advise on best practices like using virtual environments, avoiding running as root, or updating pip itself.
fix Review the pip output for specific recommendations, such as running pip in a virtual environment (`python -m venv .venv; source .venv/bin/activate; pip install ...`), avoiding running as the root user, and ensuring pip is up-to-date (`pip install --upgrade pip`). These are typically environment-specific best practices rather than pytest-mock issues.
python os / libc status wheel install import disk
3.10 alpine (musl) - - - -
3.10 slim (glibc) - - - -
3.11 alpine (musl) - - - -
3.11 slim (glibc) - - - -
3.12 alpine (musl) - - - -
3.12 slim (glibc) - - - -
3.13 alpine (musl) - - - -
3.13 slim (glibc) - - - -
3.9 alpine (musl) - - - -
3.9 slim (glibc) - - - -

This quickstart demonstrates using the `mocker` fixture to patch `os.path.exists` and `builtins.open` to simulate file system interactions without touching actual files. The first test verifies behavior when a file exists, and the second when it doesn't. `mocker.patch` automatically handles cleanup after each test.

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 == {}