django-targeted-mocking について
Django のテストで、低速・外部・非決定的な境界に絞った、インターフェースを考慮したモックを選ぶためのスキルです。依存関係を分離しながら、検証対象の動作を覆い隠さない方法を示します。
主な機能
- 01境界に基づくモック判断
- 02依存関係の参照箇所へのパッチ
- 03Django の設定用ヘルパー
- 04インターフェース準拠のモックとフェイク
- 05意図しない外部 HTTP の遮断
活用シーン
- 01外部 HTTP サービス連携のテスト
- 02設定、時刻、コマンド出力の制御
- 03リクエスト動作を隠すモックの回避
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ lvtd-llc/ skills --skill django-targeted-mockingインストール後、Claude Code で/django-targeted-mockingを入力して読み込まれたか確認します。
同梱ファイルreferences/mocking-patterns.md
詳細
Django の対象を絞ったモック
モックは、低速、不確定、外部依存、または実行が難しい境界でのみ使用します。広範囲にモックを使うとテストは速くなることがありますが、検証できる内容が減るため、フレームワークのヘルパーやインターフェースを検証できる代替手段を優先してください。
境界に関するワークフロー
-
モックが必要かどうかを判断します。
- ローカルのドメインロジックには実際のコードを優先します。
- 外部 HTTP、時刻、設定、出力/入力、高コストなサービスとの接点をモックします。
-
テスト対象のコードが依存関係を参照する場所にパッチを当てます。
- テスト対象のモジュールが使用するインポート済みのシンボルにパッチを当てます。モジュールが元のライブラリのパスから参照している場合を除き、元のライブラリのパスにはパッチを当てないでください。
-
目的に合ったツールを優先します。
- 設定:
override_settings、modify_settings、または pytest-django のsettingsフィクスチャ。 - 出力:
io.StringIO、pytest のcapsys、またはコマンドのテストヘルパー。 - HTTP:手書きのレスポンスには
requests-mock、記録したレスポンスには VCR.py。 - 時刻:可能であれば時刻をパラメーターとして渡します。それ以外の場合は
time-machineなど、時刻に特化したツールを使用します。
- 設定:
-
インターフェースを考慮したモックを作成します。
autospec=True、spec、spec_set、create_autospec、または小規模なフェイクオブジェクトを使用します。- インターフェースが重要な場合、素の
Mock/MagicMockは避けてください。
-
想定外の外部向け HTTP 通信を遮断します。
- 通常のテスト実行では、テストが意図せずネットワークにアクセスした場合に失敗するようにします。
具体的なパターンについては、mocking-patterns.md を参照してください。
判断ルール
django.conf.settingsへの直接代入ではなく、Django の設定ヘルパーを使用します。- 必要な属性が少数の場合は、自作のフェイクまたは
types.SimpleNamespaceを優先します。 - 自分で制御する決定論的な API レスポンスには
requests-mockを使用します。 - 実際に記録したレスポンスが有用で安全に保存できる場合は、VCR.py を使用します。
- CI では、カセットがない場合に記録するのではなく失敗するよう、VCR の記録モードを設定します。
- 実行環境全体で一貫して時刻をモックします。複数の datetime 関数に手作業でパッチを当てないでください。
- テストで動作を検証する対象のコンポーネントはモックしないでください。
よくある間違い
- 設定に直接パッチを当て、テスト間で状態を漏らしてしまう。
- タイプミスの属性や誤った呼び出しシグネチャも受け入れる、何でも受け付ける
MagicMockオブジェクトを使用する。 - テストから実際の外部サービスへのアクセスを許してしまう。
- CI で VCR のカセットを記録する。
- ビューの内部ヘルパーを過度にモックし、リクエストの動作をテストできなくなる。
- 間違ったインポートパスにパッチを当て、モックが有効だと思い込む。
検証
完了する前に、以下を確認してください。
- 各モックには、境界に応じた明確な理由があります。
- インターフェースが重要なモックには、仕様またはフェイクを使用しています。
- 通常のテストスイートでは、想定外の外部向け HTTP 通信が遮断されています。
- 設定は Django または pytest のヘルパーによって自動的に復元されます。
- テストではモックの呼び出しだけでなく、動作も検証しています。
コメント
Markdown 対応