はじめに
こんにちは。株式会社アイスリーデザインの芹田です。
第1部では、「なぜ単体テストをするのか」「単体とは何か」「読みやすいテストの型」を整理しました。
次は、「このテストは、良いの? 悪いの?」という疑問にぶつかります。
網羅率でも本数でもなく、判断できる物差しが欲しい。そこを深掘りしてくれるのが第2部です。
本記事は、その読書メモの第2部を、次の流れで自分なりに噛み砕いてまとめたものです。
物差し → モックで検証する相手 → 検証の手法 → 投資先の選び方
理解しやすいよう言い換えた箇所もあるため、厳密な用語とは異なる表現があるかもしれませんが、同じように「良い/悪い」の判断軸が欲しい方のきっかけになれば幸いです。
物差し 〜良いテストを構成する4本の柱〜
第4章の核心は、「良いテスト」を感覚ではなく、4つの観点で語ることです。
| 柱 | 現場で言うと |
|---|---|
| リグレッション(デグレ)への保護 | バグをどれだけ検出できるか |
| リファクタリング耐性 | 設計を直しても、テストが誤って落ちないか |
| 迅速なフィードバック | テストがどれだけ速く返ってくるか |
| 保守のしやすさ | 読んで・直して・実行するのが楽か |
「リグレッションへの保護」は、第1部で「リグレッション(デグレ)防止」と書いた価値と同じ観点です。ここでは第4章の柱名に合わせて「保護」と表記します。
本書では、「4本のうち1つでも欠けているテストには価値がない」と言っています。(正直、ここはかなり厳しい基準だと感じました…)
言い換えると、テストの価値は4つの掛け算のような関係で、どれかがゼロなら全体もゼロ、という考え方です。完璧である必要はありませんが、ゼロの柱を残さない、という意味だと理解しました。
一方、リグレッションへの保護・リファクタリング耐性・迅速なフィードバックの3つは、1本のテストで同時に最大化できません。
だからこそ、テストの種類ごとに役割を分ける「テストピラミッド」の考え方が成り立ちます。単体は速く狭い範囲を守り、E2E は広く遅い、といった分担です。

モック 〜検証対象を間違えると壊れる〜
第5章では、前章の4本柱の観点から、モックの使い方を見ます。
モックが壊れやすくなるのは、道具そのものが悪いからではありません。「どの相手とのやりとりを検証するか」という対象選びを誤ることが原因です。
たとえば「注文を確定したら、確認メールを送る」という機能を想像してください。
| 適切な対象(外部との約束) | 不適切な対象(内部の実装詳細) | |
|---|---|---|
| 検証内容 | 「確認メールを送る」という外部への約束が守られたか | 注文クラスが、内部の別クラスのメソッドをこの順番で呼んだか |
| なぜそう言えるか | アプリの外(メールサービス)とのやりとりだから | アプリの中のクラス同士のやりとりだから |
| モックで見てよいか | よい(「送られたか」を見てよい) | よくない(設計を直すたびに呼び出し順が変わり、テストだけが落ちやすい) |
前者はビジネス上の約束(観察可能な振る舞い)です。後者は実装の詳細です。第4章の「リファクタリング耐性」を自分で壊してしまうのが、後者のパターンです。
書籍では、この違いを次の2つに分けています。
| 種類 | 何か | モックで検証してよいか |
|---|---|---|
| システム間コミュニケーション | アプリと外部(メール、決済、他サービス)とのやりとり | よい(外から見える約束) |
| システム内コミュニケーション | アプリ内のクラス同士のやりとり | よくない(実装の詳細) |
ここでいう「よい」は、外部サービスの内部実装まで縛る話ではありません。アプリが外部に対して持つ契約のうち、観察できる最小限を検証する、という意味です。
あわせて、置き換えたあとの「検証する/しない」も押さえておきます。コマンド/クエリは操作の分類、モック/スタブは置き換える道具の分類です。
| テストダブル | 扱い | |
|---|---|---|
| 状態を変える・起こす操作(コマンド) | モック | 呼ばれたか・契約に必要な範囲でどう呼ばれたかを検証する |
| データを返すだけの操作(クエリ) | スタブ | 値を返すだけ。呼び出しは検証しない |
コマンドは「何かを変える・起こす操作」、クエリは「データを返すだけの操作」です。スタブは、テスト条件を作るために値を返す置き換えなので、「スタブが呼ばれたか」まで検証してはいけません。
まとめると、
- モックは外部との境界で使うこと。
- クラス同士の内部の呼び方まではモックで縛らないこと。
- スタブとのやりとりは検証しないこと。
ということでした。
第1部で「共有依存だけをテストダブルに置き換える」と整理した方針が、ここで「どこを検証するか」まで具体的になってきます。
手法 〜何を見て「成功」と判定するか〜
第6章では、検証の仕方が3つに整理されます。
| 手法 | 何を検証するか |
|---|---|
| 出力値ベーステスト | 返ってくる値 |
| 状態ベーステスト | 実行後に残る状態 |
| コミュニケーションベーステスト | 他オブジェクトとのやりとり |
(本書でいう「古典学派」は、第1部で触れた「単体=1つの振る舞い」と捉え、共有依存だけをテストダブルに置き換える立場のことです。)
古典学派の考え方では、デフォルトの優先順位として「出力値ベース > 状態ベース > コミュニケーションベース」と整理されています。これは「状態ベースは禁止」という意味ではなく、選べるなら出力を優先する、という話です。
注意点はシンプルです。
- 状態ベースでは、プライベートな状態を公開してまで検証しない
- コミュニケーションベースは、アプリの境界を超え、外部から確認できる副作用があるときに限る
第5章の「境界だけモックする」と、ここで1本につながります。
正直なところ、第6章は技術寄りの話が多く、私にとっては難しく感じた箇所もありました。それでも、「何をもって成功と言えるのか」を3つに分けて考えるだけでも、既存テストの見直しには十分使えそうだと思いました。
投資先 〜単体テストをどこに寄せるべきか〜
物差し・検証する相手・手法が揃っても、「どこに書くか」がずれると、テストは増えても価値は上がりません。第7章の主題はここです。
コードは、次の2軸で4種類に分けられます。
- コードの複雑さ/ドメインにおける重要性
- 協力者オブジェクトの数(テスト対象が依存している他のクラスやモジュールの数)
| 種類 | 複雑さ/ドメイン重要性 | 協力者オブジェクト | 単体テストの扱い |
|---|---|---|---|
| ドメインモデル/アルゴリズム | 高い | 少ない | いちばん価値が高い。寄せる本命 |
| コントローラ | 低め | 多い | 単体より統合寄り |
| 過度に複雑なコード | 高い | 多い | リファクタリング対象(ロジックと難しい依存を分ける) |
| 取るに足らないコード | 低め | 少ない | 優先度は低い。書かない選択もあり |
単体テストの価値が最も高いのは、複雑またはドメインで重要なコードです。
本書では、次の方針を推奨していました。
- ドメインで重要なコードに協力者をたくさん含めない。
- 複雑さや重要性が上がるほど、協力者の数を減らす。
もう1つの核心は、第1部の落とし穴①と地続きです。
質の悪いテストを作るくらいなら、その種のテストは全く作らない方がよい。
「書かない」は放棄ではなく、価値の低いテストを無理に増やさない、という意味で、負債になるものは増やさないほうが良いということです。
第7章も設計の話が深く難解でしたが、「単体テストは全部に均等に書くものではない」という点は、しっかりと理解できました。

第2部の学び
| 章 | 学び |
|---|---|
| 第4章 物差し | 4本柱で良い/悪いを語る。 |
| 第5章 モック | 境界だけモック。内部は縛らない。 |
| 第6章 手法 | 出力を優先。やりとりの検証は境界外に限る。 |
| 第7章 投資先 | ドメイン/アルゴリズムに寄せる。悪いテストなら書かない。 |
第1部の「振る舞い単位・共有依存のみテストダブル化」は、第2部を読み終えた時点でも維持できる、というのが私の現時点の考えです。
まとめ・すぐに使えるチェックリスト
第2部では、良い/悪いを測る物差しと、モック・手法・投資先の選び方を見てきました。
私にとって非常に参考になる内容で、これまでより自信を持って品質活動を進められると感じました。
一方で、技術的な記述が多く、読み解くのに苦労しました…。理解しきれていない部分もあるので、またしばらくしたら読み返したいと思っています。
ここまでが本書の前半です。後半では、ここでの理解がさらに深まりそうだと感じています。
単体テストの良し悪しに迷う場面は、私を含めて少なくないと思います。そうした方が現場ですぐ見直せるポイントを、古典学派を前提に方針/運用/技術へ分けてまとめたので、参考にしていただければ幸いです。
単体テストの方針(何をテストするか)
テストの狙いが正しいかを見る観点。コードを読めなくても、PM・QA が判断に加われます。
- 4本柱のうち、ゼロになっている柱がないか(どの柱を優先し、どこを妥協したかを説明できるか)
- ビジネスロジックや重要なルール(ドメインモデル/アルゴリズム)にテストが寄っているか
- 取るに足らないコードや、価値の低いテストを無理に増やしていないか
- 質の悪いテストなら、書かない(または統合テストへ移す)選択をしているか
単体テストの運用観点(コードを読まずに判断できる)
テストの外側から見える情報だけで判断できる観点。技術に詳しくなくても確認できます。
- テスト名から、ビジネス上の振る舞い(何を検証しているか)がわかるか
- 実行時間が短く、開発中に繰り返し回せる速度を保てているか
- CI に組み込まれ、繰り返し実行されているか
- 設計変更のたびに、振る舞いを変えていないのにテスト修正が増えていないか
単体テストの技術的チェック(コードを読んで判断する)
テストコードの中身を読める人が見る観点。
- モックがシステム間(外部との境界)に限定されているか
- スタブとのやりとりを検証していないか
- 検証は出力値ベースを優先し、コミュニケーションベースは境界外の副作用に限っているか
- 状態検証のために、プライベートな状態を公開していないか
- 過度に複雑なコードを、そのまま単体テストで無理にカバーしていないか
本記事は、Vladimir Khorikov 著『単体テストの考え方・使い方』(マイナビ出版)第2部を読んだメモをもとに執筆しています。











▼リリース前は気が重い——『単体テストの考え方・使い方』第1部を読んでまとめてみた
https://tech.i3design.jp/unit-testing-guide-part1/