{"id":568,"library":"pytest-mock","title":"pytest-mock","description":"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.","status":"active","version":"3.15.1","language":"python","source_language":"en","source_url":"https://github.com/pytest-dev/pytest-mock/","tags":["pytest","testing","mocking","fixtures"],"install":[{"cmd":"pip install pytest-mock","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Required as a pytest plugin; version >=6.2.5 is needed since pytest-mock v3.13.0.","package":"pytest","optional":false},{"reason":"Requires Python >=3.9 since pytest-mock v3.15.0.","package":"python","optional":false}],"imports":[{"note":"The `mocker` fixture is automatically provided by pytest-mock; no explicit import statement is usually needed for the fixture itself.","symbol":"mocker","correct":"def test_example(mocker): ..."},{"note":"Available for type annotation purposes since v3.14.0.","symbol":"MockType","correct":"from pytest_mock import MockType"},{"note":"Available for type annotation purposes since v3.14.0.","symbol":"AsyncMockType","correct":"from pytest_mock import AsyncMockType"}],"quickstart":{"code":"import os\n\nclass MyService:\n    def read_config(self, filename):\n        if not os.path.exists(filename):\n            return {}\n        with open(filename, 'r') as f:\n            return {'data': f.read()}\n\ndef test_read_config_file_exists(mocker):\n    mock_exists = mocker.patch('os.path.exists', return_value=True)\n    mock_open = mocker.patch('builtins.open', mocker.mock_open(read_data='key: value'))\n\n    service = MyService()\n    result = service.read_config('config.txt')\n\n    mock_exists.assert_called_once_with('config.txt')\n    mock_open.assert_called_once_with('config.txt', 'r')\n    assert result == {'data': 'key: value'}\n\ndef test_read_config_file_not_exists(mocker):\n    mocker.patch('os.path.exists', return_value=False)\n    mocker.patch('builtins.open', side_effect=FileNotFoundError)\n\n    service = MyService()\n    result = service.read_config('non_existent.txt')\n\n    assert result == {}","lang":"python","description":"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."},"warnings":[{"fix":"Ensure your project runs on a supported Python version (currently >=3.9 for v3.15.1).","message":"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.","severity":"breaking","affected_versions":">=3.15.0 (Python 3.8), >=3.12.0 (Python 3.7), >=3.6.0 (Python 3.5)"},{"fix":"For `mocker.spy` calls on iterators, update to `mocker.spy(obj, 'method', duplicate_iterators=True)`.","message":"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`.","severity":"breaking","affected_versions":">=3.15.1"},{"fix":"Upgrade your pytest installation: `pip install --upgrade pytest`.","message":"pytest-mock now requires `pytest>=6.2.5`. Older pytest versions will cause installation or runtime issues.","severity":"breaking","affected_versions":">=3.13.0"},{"fix":"Refer to the Python packaging documentation or project's `pyproject.toml` for modern installation methods. Avoid direct `python setup.py install`.","message":"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.","severity":"breaking","affected_versions":">=3.13.0"},{"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.","message":"Prior to v3.14.0, `mocker.patch.object` could sometimes fail to be properly cleared between tests, leading to unexpected test interactions or failures.","severity":"gotcha","affected_versions":"<3.14.0"},{"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`.","message":"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.","severity":"gotcha","affected_versions":"All versions"},{"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.","message":"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.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-05-12T15:24:51.390Z","next_check":"2026-06-26T00:00:00.000Z","problems":[{"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):`).","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.","error":"NameError: name 'mocker' is not defined"},{"fix":"Install the library using pip: `pip install pytest-mock`.","cause":"The `pytest-mock` library has not been installed in the Python environment where pytest is being run.","error":"ModuleNotFoundError: No module named 'pytest_mock'"},{"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`.","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.","error":"AttributeError: module 'your_module' has no attribute 'some_function'"},{"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.","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.","error":"TypeError: 'MagicMock' object is not callable"}],"ecosystem":"pypi","meta_description":null,"install_score":0,"install_tag":"stale","quickstart_score":80,"quickstart_tag":"verified","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"stale","tag_description":"widespread failures or data too old to trust","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"verified","tag_description":"quickstart runs on critical runtimes, recently tested","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}