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

write-tests

既存コードにテストを追加する際に、適切なモックパターンを用いてテストカバレッジを向上させ、バグに対する回帰テストや特定のファイルのテストを効率的に行うことを支援するSkill。

📜 元の英語説明(参考)

Add test coverage to existing code with correct mock patterns. Use when adding tests to untested modules, writing regression tests for bugs, or user asks to test a specific file. Handles mockReset:true, vi.hoisted(), forwarding pattern, and test app builder utilities.

🇯🇵 日本人クリエイター向け解説

一言でいうと

既存コードにテストを追加する際に、適切なモックパターンを用いてテストカバレッジを向上させ、バグに対する回帰テストや特定のファイルのテストを効率的に行うことを支援するSkill。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

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

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

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

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

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して write-tests.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → write-tests フォルダができる
  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 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

既存のコードに対するテストの作成

作成前に自問すること

  • モジュールの種類は? ルートハンドラー、リポジトリ、プラグイン、ユーティリティ、またはサービス - それぞれ異なるモック戦略が必要です。
  • 影響範囲は? このモジュールは、隔離が必要な副作用(DB書き込み、API呼び出し)を持っていますか?
  • 最も近いテストファイルは? 最も近い *.test.ts を見つけて、その構造を正確に一致させます。

モジュールの種類ごとのモック戦略

モジュールの種類 戦略
ルートハンドラー テストアプリビルダー + セッションシミュレーション + app.inject()
リポジトリ モックDB接続 + カウンターベースの execute
フレームワークプラグイン 実際のフレームワークインスタンス + 選択的な依存関係のモック
純粋なユーティリティ モックなし - 入力/出力を直接テスト
DI付きのサービス 転送パターンを介して注入された依存関係をモック

モックのセットアップ (mockReset: true)

テストランナーが mockReset: true を使用している場合、インターネット上のほとんどの例は警告なしに失敗します。

const { mockFn } = vi.hoisted(() => ({
  mockFn: vi.fn(),
}));

vi.mock("./dependency", () => ({
  dependency: (...args: unknown[]) => mockFn(...args),
}));

beforeEach(() => {
  // ここで再構成する必要があります - mockResetはテスト間で戻り値をクリアします
  mockFn.mockResolvedValue(defaultResult);
});

複雑なTDZ(一時的デッドゾーン)の場合(複数の相互依存するモック)、globalThisレジストリパターンを使用します。

絶対にしないこと

  • mockResolvedValueOnce を絶対にチェーンしないでください - mockReset はテスト間でチェーンをクリアします。代わりにカウンターベースの mockImplementation を使用してください。
  • モジュールスコープでモック変数を定義し、vi.mock() ファクトリで参照しないでください - ホイスティングは一時的デッドゾーンを作成します。 vi.hoisted() または globalThis を使用してください。
  • 副作用のあるモジュールに対して vi.importActual() を絶対にしないでください - 選択的な再エクスポートを使用してください。
  • 実装の詳細(プライベートな状態、内部呼び出し順序)を絶対にテストしないでください - パブリックAPIを通じて動作をテストしてください。
  • 他のプロジェクトからモックパターンを絶対にコピーしないでください - 最初にYOURテストランナーの設定を確認してください。
  • ソースコードを絶対に修正しないでください - このスキルはテストのみを作成します。

メタ認知ルール

最初の実行で3つ以上のテストが失敗した場合: STOP。根本原因は、個々のテストロジックのエラーではなく、すべてのテストに影響を与えるモック配線の問題である可能性が非常に高いです。テストを1つずつ修正する前に、モックのセットアップ戦略を全体的に再検討してください。

実行

npx vitest run <test-file> --reporter=verbose

引数

  • $ARGUMENTS: カバーするソースファイルまたはモジュールへのパス
    • 例: /write-tests src/routes/admin/settings.ts
    • 空の場合、テストカバレッジが必要なファイルをユーザーに尋ねます
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

Write Tests for Existing Code

Before Writing, Ask Yourself

  • Module type? Route handler, repository, plugin, utility, or service — each has a different mock strategy
  • Blast radius? Does this module have side effects (DB writes, API calls) that need isolation?
  • Nearest test file? Find the closest *.test.ts and match its structure exactly

Mock Strategy by Module Type

Module Type Strategy
Route handler Test app builder + session simulation + app.inject()
Repository Mock DB connection + counter-based execute
Framework plugin Real framework instance + selective dependency mocks
Pure utility No mocks — test inputs/outputs directly
Service w/ DI Mock injected deps via forwarding pattern

Mock Setup (mockReset: true)

If your test runner uses mockReset: true, most examples from the internet will silently fail.

const { mockFn } = vi.hoisted(() => ({
  mockFn: vi.fn(),
}));

vi.mock("./dependency", () => ({
  dependency: (...args: unknown[]) => mockFn(...args),
}));

beforeEach(() => {
  // MUST reconfigure here — mockReset clears return values between tests
  mockFn.mockResolvedValue(defaultResult);
});

For complex TDZ cases (multiple interdependent mocks), use the globalThis registry pattern.

NEVER

  • NEVER chain mockResolvedValueOncemockReset clears the chain between tests. Use counter-based mockImplementation instead.
  • NEVER define mock variables at module scope then reference in vi.mock() factories — hoisting creates a temporal dead zone. Use vi.hoisted() or globalThis.
  • NEVER vi.importActual() for modules with side effects — use selective re-exports.
  • NEVER test implementation details (private state, internal call order) — test behavior through the public API.
  • NEVER copy mock patterns from other projects — check YOUR test runner config first.
  • NEVER modify source code — this skill writes tests only.

Metacognitive Rule

If >3 tests fail on first run: STOP. The root cause is almost certainly a mock wiring issue affecting all tests, not individual test logic errors. Re-examine the mock setup strategy holistically before fixing tests one by one.

Run

npx vitest run <test-file> --reporter=verbose

Arguments

  • $ARGUMENTS: Path to the source file or module to cover
    • Example: /write-tests src/routes/admin/settings.ts
    • If empty, ask the user which file needs test coverage