jpskill.com
🛠️ 開発・MCP コミュニティ

pytest-mock-guide

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.

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o pytest-mock-guide.zip https://jpskill.com/download/17568.zip && unzip -o pytest-mock-guide.zip && rm pytest-mock-guide.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/17568.zip -OutFile "$d\pytest-mock-guide.zip"; Expand-Archive "$d\pytest-mock-guide.zip" -DestinationPath $d -Force; ri "$d\pytest-mock-guide.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して pytest-mock-guide.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → pytest-mock-guide フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-18
取得日時
2026-05-18
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

pytest-mock の使用ガイド

pytest-mock は、Python の unittest.mock パッチ API の薄いラッパーとして mocker フィクスチャを提供する pytest プラグインです。各テストの終了時に、すべてのモックを自動的に元に戻します。

mocker フィクスチャ

mocker フィクスチャは、主なインターフェースです。テスト関数でそれをリクエストします。

def test_example(mocker):
    # すべてのモックは、このテストの後に自動的にクリーンアップされます
    mock_func = mocker.patch("module.function")

利用可能なフィクスチャスコープ

フィクスチャ スコープ ユースケース
mocker function デフォルト、テストごとのモック
class_mocker class テストクラス全体でモックを共有
module_mocker module テストモジュール全体でモックを共有
package_mocker package パッケージ全体でモックを共有
session_mocker session セッション全体でモックを共有

パッチメソッド

mocker.patch(target, ...)

ドット区切りのパスでモジュールレベルのオブジェクトをパッチします。

def test_patch(mocker):
    # os.remove 関数をパッチします
    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, ...)

オブジェクトの属性を直接パッチします。

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)

辞書を一時的にパッチします。

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

    assert config["debug"] is True
    # テスト後、config["debug"] は再び False になります

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

複数の属性を一度にパッチします。

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, ...)

patch.object と同じですが、モックがコンテキストマネージャーとして使用された場合に警告を表示しません。

def test_context_manager(mocker):
    mock_open = mocker.patch.context_manager(builtins, "open")
    # `with mock_open(...)` を使用しても警告は表示されません

一般的なパッチパラメータ

パラメータ 説明
new ターゲットを置き換えるオブジェクト
return_value モックが呼び出されたときに返される値
side_effect 発生させる例外または呼び出す関数
autospec ターゲットのシグネチャに一致するモックを作成
spec 仕様として使用するオブジェクト
spec_set 新しい属性の設定を防ぐ、より厳密な仕様
create 存在しない属性のパッチを許可
new_callable モックを作成するための呼び出し可能オブジェクト

mocker.spy() によるスパイ

Spy は、呼び出しを追跡しながら、実際のメソッドをラップします。

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

    # 実際のメソッドが呼び出されます
    result = os.path.exists("/tmp")

    # ただし、呼び出しを検査できます
    spy.assert_called_once_with("/tmp")

    # 戻り値にアクセスします
    assert spy.spy_return == result
    assert spy.spy_return_list == [result]  # すべての戻り値

Spy 属性

属性 説明
spy_return 実際のメソッドからの最後の戻り値
spy_return_list すべての戻り値のリスト
spy_return_iter イテレータのコピー (duplicate_iterators=True の場合)
spy_exception 発生した最後の例外 (存在する場合)

イテレータのスパイ

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

    items = list(obj.get_items())

    # 返されたイテレータのコピーにアクセスします
    spy_items = list(spy.spy_return_iter)

スタブの作成

mocker.stub(name=None)

任意の引数を受け入れるスタブを作成します。

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

    some_function(on_complete=callback)

    callback.assert_called_once()

mocker.async_stub(name=None)

非同期スタブを作成します。

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

    await some_async_function(on_complete=callback)

    callback.assert_awaited_once()

モックヘルパー

mocker.create_autospec(spec, ...)

spec のシグネチャに一致するモックを作成します。

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

    # 間違った引数で呼び出すと TypeError が発生します
    mock_obj.method()  # method() が引数を取らない場合は OK

直接モッククラス

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()

その他のユーティリティ

def test_utilities(mocker):
    # 任意の引数に一致
    mock.assert_called_with(mocker.ANY)

    # アサーション用の呼び出しオブジェクトを作成します
    mock.assert_has_calls([mocker.call(1), mocker.call(2)])

    # Sentinel オブジェクト
    result = mocker.sentinel.my_result

    # モックファイルのオープン
    m = mocker.mock_open(read_data="file contents")
    mocker.patch("builtins.open", m)

    # 新しい属性を防ぐためにモックをシールします
    mocker.seal(mock)

モックの管理

mocker.stopall()

すべてのパッチをすぐに停止します。

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

    mocker.stopall()  # 両方のパッチが停止しました

mocker.stop(mock)

特定のパッチを停止します。

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

    mocker.stop(mock_remove)  # このパッチのみが停止しました

mocker.resetall()

停止せずにすべてのモックをリセットします。

📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

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

Fixture Scope Use Case
mocker function Default, per-test mocking
class_mocker class Share mocks across test class
module_mocker module Share mocks across test module
package_mocker package Share mocks across package
session_mocker session Share 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

Parameter Description
new Object to replace target with
return_value Value returned when mock is called
side_effect Exception to raise or function to call
autospec Create mock matching target's signature
spec Object to use as specification
spec_set Stricter spec that prevents setting new attributes
create Allow patching non-existent attributes
new_callable Callable 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

Attribute Description
spy_return Last return value from real method
spy_return_list List of all return values
spy_return_iter Iterator copy (when duplicate_iterators=True)
spy_exception Last 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"