Back to list
aiskillstore

pytest-mock-guide

by aiskillstore

Security-audited skills for Claude, Codex & Claude Code. One-click install, quality verified.

102🍴 3📅 Jan 23, 2026

SKILL.md


name: pytest-mock-guide description: Guide for using pytest-mock plugin to write tests with mocking. Use when writing pytest tests that need mocking, patching, spying, or stubbing. Covers mocker fixture usage, patch methods, spy/stub patterns, and assertion helpers.

pytest-mock Usage Guide

pytest-mock is a pytest plugin providing a mocker fixture as a thin wrapper around Python's unittest.mock patching API. It automatically undoes all mocking at the end of each test.

The mocker Fixture

The mocker fixture is the main interface. Request it in your test function:

def test_example(mocker):
    # All mocks are automatically cleaned up after this test
    mock_func = mocker.patch("module.function")

Available Fixture Scopes

FixtureScopeUse Case
mockerfunctionDefault, per-test mocking
class_mockerclassShare mocks across test class
module_mockermoduleShare mocks across test module
package_mockerpackageShare mocks across package
session_mockersessionShare mocks across entire session

Patching Methods

mocker.patch(target, ...)

Patch a module-level object by its dotted path:

def test_patch(mocker):
    # Patch os.remove function
    mock_remove = mocker.patch("os.remove")
    mock_remove.return_value = None

    os.remove("file.txt")
    mock_remove.assert_called_once_with("file.txt")

mocker.patch.object(target, attribute, ...)

Patch an attribute on an object directly:

def test_patch_object(mocker):
    import os
    mock_remove = mocker.patch.object(os, "remove")

    os.remove("file.txt")
    mock_remove.assert_called_once_with("file.txt")

mocker.patch.dict(in_dict, values, clear=False)

Patch a dictionary temporarily:

def test_patch_dict(mocker):
    config = {"debug": False}
    mocker.patch.dict(config, {"debug": True})

    assert config["debug"] is True
    # After test, config["debug"] is False again

mocker.patch.multiple(target, **kwargs)

Patch multiple attributes at once:

def test_patch_multiple(mocker):
    mocks = mocker.patch.multiple(
        "os",
        remove=mocker.DEFAULT,
        listdir=mocker.DEFAULT
    )

    os.remove("file.txt")
    os.listdir("/tmp")

    mocks["remove"].assert_called_once()
    mocks["listdir"].assert_called_once()

mocker.patch.context_manager(target, attribute, ...)

Same as patch.object but doesn't warn when mock is used as context manager:

def test_context_manager(mocker):
    mock_open = mocker.patch.context_manager(builtins, "open")
    # No warning when using `with mock_open(...)`

Common Patch Parameters

ParameterDescription
newObject to replace target with
return_valueValue returned when mock is called
side_effectException to raise or function to call
autospecCreate mock matching target's signature
specObject to use as specification
spec_setStricter spec that prevents setting new attributes
createAllow patching non-existent attributes
new_callableCallable to create the mock

Spying with mocker.spy()

Spy wraps the real method while tracking calls:

def test_spy(mocker):
    spy = mocker.spy(os.path, "exists")

    # Real method is called
    result = os.path.exists("/tmp")

    # But we can inspect calls
    spy.assert_called_once_with("/tmp")

    # Access return values
    assert spy.spy_return == result
    assert spy.spy_return_list == [result]  # All returns

Spy Attributes

AttributeDescription
spy_returnLast return value from real method
spy_return_listList of all return values
spy_return_iterIterator copy (when duplicate_iterators=True)
spy_exceptionLast exception raised, if any

Spying Iterators

def test_spy_iterator(mocker):
    spy = mocker.spy(obj, "get_items", duplicate_iterators=True)

    items = list(obj.get_items())

    # Access a copy of the returned iterator
    spy_items = list(spy.spy_return_iter)

Creating Stubs

mocker.stub(name=None)

Create a stub that accepts any arguments:

def test_stub(mocker):
    callback = mocker.stub(name="my_callback")

    some_function(on_complete=callback)

    callback.assert_called_once()

mocker.async_stub(name=None)

Create an async stub:

async def test_async_stub(mocker):
    callback = mocker.async_stub(name="async_callback")

    await some_async_function(on_complete=callback)

    callback.assert_awaited_once()

Mock Helpers

mocker.create_autospec(spec, ...)

Create a mock that matches the spec's signature:

def test_autospec(mocker):
    mock_obj = mocker.create_autospec(MyClass, instance=True)

    # Calling with wrong arguments raises TypeError
    mock_obj.method()  # OK if method() takes no args

Direct Mock Classes

Access mock classes directly through mocker:

def test_mock_classes(mocker):
    mock = mocker.Mock()
    magic_mock = mocker.MagicMock()
    async_mock = mocker.AsyncMock()
    property_mock = mocker.PropertyMock()
    non_callable = mocker.NonCallableMock()

Other Utilities

def test_utilities(mocker):
    # Match any argument
    mock.assert_called_with(mocker.ANY)

    # Create call objects for assertion
    mock.assert_has_calls([mocker.call(1), mocker.call(2)])

    # Sentinel objects
    result = mocker.sentinel.my_result

    # Mock file open
    m = mocker.mock_open(read_data="file contents")
    mocker.patch("builtins.open", m)

    # Seal a mock to prevent new attributes
    mocker.seal(mock)

Managing Mocks

mocker.stopall()

Stop all patches immediately:

def test_stopall(mocker):
    mocker.patch("os.remove")
    mocker.patch("os.listdir")

    mocker.stopall()  # Both patches stopped

mocker.stop(mock)

Stop a specific patch:

def test_stop(mocker):
    mock_remove = mocker.patch("os.remove")

    mocker.stop(mock_remove)  # Only this patch stopped

mocker.resetall()

Reset all mocks without stopping them:

def test_resetall(mocker):
    mock_func = mocker.patch("module.func")
    mock_func("arg1")

    mocker.resetall()

    mock_func.assert_not_called()  # Call history cleared

Assertion Methods with pytest Introspection

pytest-mock enhances assertion error messages with pytest's comparison:

def test_assertions(mocker):
    mock = mocker.patch("module.func")
    mock("actual_arg")

    # Enhanced error shows diff between expected and actual
    mock.assert_called_with("expected_arg")
    # AssertionError shows:
    # Args:
    # assert ('actual_arg',) == ('expected_arg',)

Available Assertions

Call Assertions:

  • assert_called() - Called at least once
  • assert_called_once() - Called exactly once
  • assert_called_with(*args, **kwargs) - Last call matches
  • assert_called_once_with(*args, **kwargs) - Called once with args
  • assert_any_call(*args, **kwargs) - Any call matches
  • assert_has_calls(calls, any_order=False) - Has specific calls
  • assert_not_called() - Never called

Async Assertions (for AsyncMock):

  • assert_awaited()
  • assert_awaited_once()
  • assert_awaited_with(*args, **kwargs)
  • assert_awaited_once_with(*args, **kwargs)
  • assert_any_await(*args, **kwargs)
  • assert_has_awaits(calls, any_order=False)
  • assert_not_awaited()

Configuration Options

In pytest.ini, pyproject.toml, or setup.cfg:

[pytest]
# Enable/disable enhanced assertion messages (default: true)
mock_traceback_monkeypatch = true

# Use standalone mock package instead of unittest.mock (default: false)
mock_use_standalone_module = false

Common Patterns

Patching Where Used (Not Where Defined)

# my_module.py
from os.path import exists

def check_file(path):
    return exists(path)

# test_my_module.py
def test_check_file(mocker):
    # Patch where it's used, not where it's defined
    mocker.patch("my_module.exists", return_value=True)
    assert check_file("/any/path") is True

Testing Exceptions

def test_exception(mocker):
    mock_func = mocker.patch("module.func")
    mock_func.side_effect = ValueError("error message")

    with pytest.raises(ValueError, match="error message"):
        module.func()

Multiple Return Values

def test_multiple_returns(mocker):
    mock_func = mocker.patch("module.func")
    mock_func.side_effect = [1, 2, 3]

    assert module.func() == 1
    assert module.func() == 2
    assert module.func() == 3

Async Function Mocking

async def test_async(mocker):
    mock_fetch = mocker.patch("module.fetch_data")
    mock_fetch.return_value = {"data": "value"}

    result = await module.fetch_data()
    assert result == {"data": "value"}

Class Method Mocking

def test_class_method(mocker):
    mocker.patch.object(MyClass, "class_method", return_value="mocked")

    assert MyClass.class_method() == "mocked"

Property Mocking

def test_property(mocker):
    mock_prop = mocker.patch.object(
        MyClass, "my_property",
        new_callable=mocker.PropertyMock,
        return_value="mocked"
    )

    obj = MyClass()
    assert obj.my_property == "mocked"

Score

Total Score

60/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

+5
最近の活動

1ヶ月以内に更新

+10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

+5

Reviews

💬

Reviews coming soon