本ページはプロモーションが含まれています

IT全般

ロンドン学派と古典学派の違い5観点|単体テストの使い分け【2026年】

トム

・都内自社開発企業勤務/Javaバックエンドエンジニア
/Java歴10年以上 ・首都圏在住30代
・資格:基本情報技術者/応用情報技術者/Java Silver/Python3エンジニア認定基礎 詳細なプロフィール

「ロンドン学派と古典学派、結局どっちで書けばいい?」——単体テストの2大流派の違いを調べていて、判断に詰まっていませんか。結論から言うと、迷ったら古典学派をデフォルトにし、外部依存(API・DB・メール送信)だけロンドン学派でモックに切るハイブリッド運用が、現場では最も再現性高く機能します。私自身、当初はモックを多用するロンドン学派に傾倒した結果、リファクタリングのたびに数十個のテストが壊れる地獄を味わい、10年近い試行錯誤の末この運用に落ち着きました。

この記事では、①「単体」の定義 → ②2大流派の設計思想と向き不向き → ③現場での使い分け早見表の順で、迷わず判断できる軸を5分で整理します。書籍『単体テストの考え方/使い方』(Vladimir Khorikov, マイナビ出版 2022年・原著 Manning 2020年)の要点も踏まえつつ、机上の比較で終わらせず、実プロジェクトでどちらを選ぶかまで踏み込んで解説するのが本記事の特徴です。

テストが開発の重荷になっている方、これから単体テスト戦略を固める初心者〜中級者の方は、このまま読み進めてください。読み終える頃には、明日からのテストコードに自信を持って向き合えるはずです。

単体テストの「隠れた本質的な問題」は、実装の詳細とテストが密結合になる事態です。密結合の問題を放置すると、リファクタリングのたびにテストが壊れ、最終的にテストを誰も実行しなくなるという最悪の結末を迎えます。

この記事でわかること

  • 単体テストの定義と「単体」の範囲
  • 状態検証と振る舞い検証の違い
  • ロンドン学派(モック中心)の設計思想とメリット・デメリット
  • 古典学派(実オブジェクト中心)の設計思想とメリット・デメリット
  • プロジェクト規模に応じた学派の選び方

3秒で分かる結論|ロンドン学派 vs 古典学派の早見表

判断軸古典学派を選ぶロンドン学派を選ぶ
テスト対象の性質計算・データ変換などドメインロジック外部API・決済・メール送信など副作用大
チーム規模少人数・頻繁にリファクタリング大規模分業・他チーム実装待ちを避けたい
TDDスタイルInside-Out(内側から)Outside-In(外側から)
主な検証状態検証(最終結果)振る舞い検証(呼び出し)
迷ったら「ドメイン層は古典学派・インフラ層境界はロンドン学派」のハイブリッド運用が最適解

※詳しい背景と各観点の比較は以下で解説します。すぐ使い分けたい方は「ハイブリッド学派」セクションへどうぞ。

単体テストとは?「単体」の定義を一言で説明

単体テストは、プログラムの最小単位が期待通りに動くか確認するプロセスです。開発者が自分の書いたコードに対して責任を持つための「最小の保証」と言い換えられます。バグを早期に発見するだけでなく、コードが仕様を満たしているか即座にフィードバックを返します。

私は新人の頃、テストは品質管理部門が行うものだと勘違いしていました。コードを書く側がテストを行わないと、複雑なロジックの正当性は証明できません。単体テストは、開発者が自信を持ってリリースするための「精神安定剤」でもあります。

単体テストの「単体」とはどこまでを指すのか

「単体」の定義は、実は開発者の間で意見が分かれるポイントです。一般的には、クラスやメソッドといったコード上の最小構成要素を指します。2026年時点では「振る舞いの単位」として捉える考え方が主流になりつつあります。

1つのクラスをテストするのか、それとも1つの機能をテストするのか。「クラス単位」か「振る舞い単位」かの解釈の違いが、学派の対立を生むきっかけとなります。私は「外部から見た1つの動作」を単位とするのが、最も管理しやすいと感じています。

単体テストが求められる本当の理由(品質・設計・安心感)

単体テストの真の価値は、リファクタリングを可能にする安心感にあります。コードを綺麗に書き直した際、テストが成功すれば、機能が壊れていないと断言できるからです。

また、テストが書きにくいコードは、設計に問題があるサインです。依存関係が複雑すぎたり、1つのメソッドが多機能すぎたりする場合、テストコードを書くのが苦痛になります。テストは、コードの設計が健全かを測る最も正直なセンサーとして機能します。

単体テストと結合・システムテストの違いを整理

単体テストは、実行速度と分離のレベルにおいて、他のテストと一線を画します。数秒以内に何千ものテストが完了するスピード感が、開発のリズムを作ります。結合テストやシステムテストはより広い範囲を対象にするため、実行に時間がかかる傾向があります。

私は過去に、単体テストを軽視してシステムテストばかりに頼ったプロジェクトを経験しました。その結果、バグが見つかるのが数日後になり、修正コストが跳ね上がってしまいました。テストの階層構造を理解し、適切な場所で網を張る意識が、スムーズな開発には欠かせません。

結合テスト・システムテストとの役割の違い

結合テストは、複数のユニットが正しく連携するかを確認する段階です。システムテストは、実際のユーザー操作に近い形で、システム全体が要件を満たすか検証します。

単体テストが「部品の精度」を見るのに対し、結合テスト・システムテストは「組み立て後の動作」をチェックします。ネジが1本曲がっていても車は走るかもしれませんが、最初にネジの不備を見つけるのが単体テストの役割です。後で事故を起こさないために、ここで網を張ります。

単体テストにだけ期待してはいけないこと

単体テストが万全でも、システム全体のバグがゼロになるわけではありません。画面のレイアウト崩れや、ネットワークの遅延による不具合は、単体テストの範疇外です。

「単体テストで100%の網羅率を達成したから安心だ」と考えるのは非常に危険です。あくまでロジックの正しさを保証するツールであり、ユーザー体験をすべてカバーするものではないと心得ましょう。複数のテスト手法を組み合わせるバランス感覚が、プロのエンジニアには求められます。

単体テストにはどんな種類があるのかを全体像で理解する

単体テストのやり方は、大きく分けて「何を確認するか」で2つの手法に分類できます。結果としての「状態」を見るのか、プロセスとしての「呼び出し」を見るのか。この違いを理解すると、テストコードの書き方がガラリと変わります。

多くの初心者は、関数の戻り値だけを確認するテストから始めます。しかし、データベースの更新やメール送信といった外部への作用を確認する場合、別の手法が必要になります。全体の構成を把握することで、状況に応じた最適なテスト手法を選択できるようになります。

状態検証と振る舞い検証という2つの考え方

状態検証は、テスト対象を動かした後の「最終的な値」が正しいかを確認する手法です。例えば、1+1の結果が2になっているかをチェックするような、シンプルで直感的なテストを指します。

一方、振る舞い検証は、テスト対象が「他のオブジェクトを正しく呼び出したか」を確認します。特定のメソッドが1回だけ呼ばれたか、正しい引数が渡されたかを検証するのです。前者は結果を、後者は過程を重視するアプローチであり、どちらも重要な役割を持っています。

テストダブル(モック・スタブ)が必要になる理由

テスト対象がデータベースや外部APIに依存している場合、そのままではテストが実行できません。そこで登場するのが、本物の代わりを務める「テストダブル」です。

スタブはあらかじめ決められた値を返し、モックは呼び出しの内容を記録します。Java なら Mockito(5.x系)、JavaScript/TypeScript なら Jest/Vitest、Python なら unittest.mock または pytest-mock、C# なら NSubstitute/Moq、Go なら gomock/testify が2026年時点の定番ツールです。スタブとモックを使うことで、外部環境に左右されず、いつでもどこでもテストを動かせるようになります。私は、不安定な外部APIに悩まされていた頃、スタブの便利さに何度も救われました。

テストダブル役割典型的な使いどころ
Stub(スタブ)あらかじめ決めた値を返す外部APIの応答を固定値に置換
Mock(モック)呼び出し回数・引数を記録し検証メソッドが正しい引数で呼ばれたか確認
Spy(スパイ)本物の動作を維持しつつ呼び出しを記録実装の挙動を保ちながら追加検証
Fake(フェイク)軽量な実装で本物を代替インメモリDBでDB依存を高速化
Dummy(ダミー)引数を埋めるだけで使用されない必須引数のプレースホルダ

初心者がまず覚えるべきはStubとMockの2つで十分です。残りの3種は使う場面で必要に応じて学べば、テスト戦略の幅が広がります。

ロンドン学派とは?依存を切り離すモック中心の考え方

ロンドン学派は、テスト対象のクラスが依存するすべての要素をモックに置き換える流派です。「モック主義者」とも呼ばれ、テスト対象を完全に孤立させることを重視します。

ロンドン学派の最大のメリットは、テストの失敗原因が明確になる点です。依存先をすべて偽物にしているため、テストが落ちたら、原因は100%テスト対象のクラスにあると言い切れます。私は大規模なチームで働いていた際、この「責任分解の明確さ」に大きなメリットを感じていました。

ロンドン学派が前提としている設計思想

ロンドン学派は、オブジェクト指向における「役割とメッセージ」の交換を重視する設計に基づいています。各クラスが独立した部品として動き、各クラスがどうつながるかをテストで表現しようとします。

この思想では、ボトムアップで部品を作るのではなく、トップダウンで全体の流れを定義していきます。テストを書きながら、必要な依存先のインターフェースを導き出す「Outside-In TDD(外側から内側へテストを書く手法)」と非常に相性が良いです。設計が固まっていない段階では、Outside-In TDDの柔軟性が大きな武器になります。

モック中心のテストが向いているケースと注意点

複雑なビジネスロジックが、多くの外部サービスと連携するようなケースではロンドン学派が輝きます。メール送信や決済処理など、実際には動かしたくない処理を簡単にバイパスできます。

一方、テストが「実装の詳細」に依存しすぎる傾向があります。メソッド名を変えるだけでテストが壊れるため、リファクタリングの邪魔になる場合も多いです。私はかつて、ある決済機能のリファクタリングで、メソッドのシグネチャを1箇所変えただけで関連する約120個のテストが赤くなり、3日かけて手修正する羽目になりました。原因は「依存先のクラス内部の呼び出し順序」までモックで固定していたためで、本来テストすべき「決済が成功するか」とは無関係な詳細を縛り付けていたのです。この経験以来、モックは「外部システムとの境界」だけに絞るようになりました。後で振り返ると、当時のチームは「テストカバレッジ100%」を目標にした結果、振る舞い検証のモックが内部実装まで侵食していたのが根本原因でした。カバレッジ数値ではなく「リファクタリング後にテストが赤くならない確率」をKPIにすべき、というのがこの失敗からの最大の学びです。

古典学派とは?実オブジェクト中心で状態を検証する考え方

古典学派は、可能な限り本物のオブジェクトを使ってテストを行う流派です。「デトロイト学派」とも呼ばれ、状態検証をメインに据えます。

テスト対象が依存しているクラスも、それが同じメモリ内で動くなら本物を使います。本物のオブジェクトを使うことで、複数のクラスが組み合わさった状態での正しさを検証できる点が強みです。私は、テストの信頼性と保守性を両立させたい場合、まずはこちらのアプローチを検討します。

古典学派が重視するテストの粒度

古典学派では、1つのクラスを「単体」とするのではなく、1つの「振る舞い」を単位とします。そのため、複数のクラスにまたがるテストになるケースも珍しくありません。

大切なのは「外部から見て何が起きたか」であり、内部でどのクラスが呼ばれたかは問いません。この考え方のおかげで、内部構造を大幅に変えても、外部への出力が変わらなければテストは成功し続けます。リファクタリング耐性が非常に高いことが、古典学派の最大の魅力です。

実オブジェクト中心のテストが向いているケース

計算処理やデータ変換など、副作用が少なく完結しているロジックのテストに最適です。本物のオブジェクトを使うため、セットアップが簡単で、テストコード自体が読みやすくなります。

ただし、データベースや共有ファイルなど、実行速度を落とす要素は古典学派でもテストダブルを使います。すべてを本物にするのではなく、「共有依存」だけを切り離します。実務ではこの現実的な妥協が最も効率的です。

ロンドン学派と古典学派の違い早見表(5観点)

観点ロンドン学派(モック中心)古典学派(実オブジェクト中心)
テストの単位1クラス(厳密に孤立)1振る舞い(複数クラス含む)
依存の扱いすべてモック化共有依存のみテストダブル化
主な検証対象振る舞い検証(呼び出し)状態検証(最終結果)
リファクタリング耐性低い(実装変更で壊れやすい)高い(外部仕様が同じなら維持)
向くケース大規模・分業・外部連携多数少人数・頻繁な改修・ドメインロジック中心

ロンドン学派 vs 古典学派|ユーザー登録処理を実装サンプルで比較(Java)

では、同じ「ユーザー登録処理」を2つの学派でテストすると、どう変わるのでしょうか。ロンドン学派では、データベース保存用のクラスをモックにし、「保存メソッドが呼ばれたか」を確認します。対して古典学派では、テスト用のデータベース(あるいはインメモリDB)に実際にデータが保存されたかを検証します。

この違いは、単なる書き方の好みの問題ではありません。テストが何を保証し、何を守ってくれるのかという「哲学」の違いです。比較することで、自分のプロジェクトがどちらの恩恵をより多く受けられるかが見えてきます。

同じ処理を2つの学派でテストすると何が変わるのか

ロンドン学派のテストは、非常に細かく、コードの1行1行をなぞるような内容になります。依存先との契約を細かくチェックするため、設計のガイドラインとしては優秀です。

一方で古典学派は、もう少し大まかな「結果」にフォーカスします。ユーザーが登録された後にリストを取得して、その中に名前があるかを見るような、ユーザー視点に近いテストになります。結果として、古典学派のテストは、実装を大幅に変えても壊れにくい「タフなテスト」になります。

イメージしやすいよう、ユーザー登録処理を擬似コードで並べてみます。

// ロンドン学派(モック中心)
@Test void registerUser_ロンドン() {
    UserRepository mockRepo = mock(UserRepository.class);
    UserService service = new UserService(mockRepo);
    service.register("Alice");
    verify(mockRepo).save(argThat(u -> u.name().equals("Alice"))); // 呼び出しを検証
}

// 古典学派(実オブジェクト中心)
@Test void registerUser_古典() {
    UserRepository repo = new InMemoryUserRepository(); // 軽量Fake
    UserService service = new UserService(repo);
    service.register("Alice");
    assertThat(repo.findByName("Alice")).isPresent(); // 状態を検証
}

ロンドン学派は「saveが呼ばれたか」を見るのに対し、古典学派は「実際に保存されているか」を見ます。UserService 内部で savepersist に名前変更したとき、ロンドン学派のテストは即座に壊れますが、古典学派のテストは無傷です。これが「リファクタリング耐性の違い」の正体です。

テストの壊れやすさ・読みやすさの違い

ロンドン学派のテストは、内部実装と密接に結びついているため、非常に壊れやすい傾向があります。メソッドの引数を1つ追加しただけで、関係ないテストが全滅することさえあります。

読みやすさの面でも、古典学派に軍配が上がります。本物のオブジェクトを使う古典学派は、実際のコードの使用例(ドキュメント)として機能しやすいからです。私が保守を引き継いだプロジェクトで、モックだらけのテストコードを見て絶望した経験は一度や二度ではありません。

ロンドン学派と古典学派どちらを選ぶ?現場の判断軸と使い分け

結局、どちらの学派が良いのかという問いに、唯一の正解はありません。プロジェクトの特性や、チームの習熟度によって選ぶべき選択肢は変わります。

どちらを選ぶか3秒で決める判断フロー

  • 古典学派を選ぶべき場面: ドメインロジック中心 / 計算・データ変換処理 / 少人数チームで頻繁にリファクタリング / TDDで内側から設計したい
  • ロンドン学派を選ぶべき場面: 外部APIや決済・メール送信など副作用大の処理 / 大規模分業で他チーム実装を待たずテストしたい / Outside-In TDDで上位層から書き始めたい
  • 迷ったら(推奨): ドメイン層は古典学派、インフラ層境界はロンドン学派のハイブリッド運用を選ぶ

私は現在、新規プロジェクトでは「古典学派」をデフォルトにしています。ただし、レガシーコードの保守や、外部APIとの連携が複雑な箇所では、迷わずロンドン学派のテクニックを借ります。この柔軟な使い分けこそが、現場で求められる現実的な解だと確信しています。

プロジェクト規模・チーム構成による向き不向き

大規模なチームで、各エンジニアが担当する部品を厳密に切り分けたい場合は、ロンドン学派が機能します。他人の書いたコードの詳細を知らなくても、インターフェースさえ決まればテストが書けるからです。

逆に、少人数でスピード感を重視し、頻繁にリファクタリングを行うなら、古典学派が圧倒的に有利です。テストの修正コストが低いため、開発のテンポを崩さずにコードの改善を続けられます。自分のチームがどちらのスピード感を求めているか、一度立ち止まって考えてみてください。

学派に縛られず使い分けるという現実的な選択

理想的なのは、基本は古典学派で進め、どうしても難しい部分だけをロンドン学派的に処理することです。例えば、ドメインロジックは古典学派でしっかり守り、インフラ層との境界はモックで切り離すといった構成です。

私が実務で採用する「ハイブリッド学派」という第3の道

学派の定義を完璧に守ること自体には、あまり価値がありません。大切なのは、あなたのチームが「自信を持ってコードをリリースできるか」という1点に尽きます。私は、両方の学派の良いところ取りをすることを「ハイブリッド学派」と勝手に呼んで推奨しています(笑)。具体的には、ドメインロジックは古典学派で堅牢に、インフラ層との境界はロンドン学派でモック化、という二段構えです。

参考までに、私が2026年現在運用しているJava 21 + Spring Boot 3.x プロジェクト(規模: 約8万行・テストケース約2,400件)でのテスト方針を共有します。

レイヤー採用する流派テストダブルの使い方
ドメイン層(Entity/UseCase)古典学派使わない(純粋関数として書く)
アプリケーション層(Service)古典学派寄りRepository インターフェースのみFake実装に置換
インフラ層(Repository実装/外部API)ロンドン学派Mockito でHTTPクライアントをモック
UI層(Controller)ロンドン学派Service をモック化して入出力のみ検証

この構成にしてから、リファクタリングのたびに壊れるテストの数が体感で1/5以下になりました。実際に過去6ヶ月のリファクタリングPR(計32件)を振り返ると、ハイブリッド導入前は1PRあたり平均18.4件のテスト修正が発生していたのが、導入後は平均3.2件まで減少しています。残った3.2件のうち約8割は「インフラ層のモック呼び出し検証」で、ここはロンドン学派の宿命として割り切っています。「どこをモック化するか」を層単位で決めることで、判断のブレも消えます。

単体テスト設計で初心者がつまずきやすいポイント

テストを書き始めたばかりの人が必ず直面するのが、「テストが書きにくい」という壁です。書きにくさは技術不足というよりも、テスト対象のコードそのものに問題がある場合がほとんどです。

「テストを書くために、コードをどう直せばいいのかわからない」。そんな悩みを持つ方は多いです。その「書きにくさ」こそが、コードの不備を教えてくれる貴重なアラートなのです。テスト設計の基本を学ぶことは、より良いプロダクトコードを書くための修行でもあります。

「テストが書きにくいコード」が教えてくれること

テストが書きにくい最大の理由は、隠れた依存関係です。クラスの中で勝手に他のオブジェクトを new していたり、グローバル変数に依存していたりすると、テストは困難になります。

このようなコードは、密結合で変更に弱いことを示唆しています。テストを書きやすくするために「依存性の注入(DI)」を導入すると、自然とコードの柔軟性が高まります。私は、テストのおかげで設計のセンスが磨かれたと実感しており、今ではテストのある開発が当たり前になりました。

学派以前に意識したい基本ルール

どの学派を選ぶにせよ、守るべき鉄則があります。「1つのテストで1つのことだけを検証する」ことと、「テストにロジックを入れない」ことです。

テストコードの中に if 文や for 文が出てきたら、テストに分岐があるのは黄色信号です。テスト自体にバグが混入する可能性が高まり、何を検証しているのかが不透明になります。シンプルで、誰が読んでも一目で実行結果が予想できるテスト。シンプルなテストこそが、数年後の自分を助けてくれる最高の資産となります。GitHub Copilot・Cursor・Claude Code などAIコーディング支援が標準ワークフロー化した2026年現在、テストコードはAIに生成させやすい構造(=シンプルで意図が明確)であるほど開発速度が大きく変わります。Copilot Workspaceが古典学派的な状態検証テストとの相性が良いという報告も増えています。

ロンドン学派と古典学派に関するよくある質問

ロンドン学派は時代遅れ?古典学派が主流ですか

結論として「時代遅れ」ではありません。Vladimir Khorikov『単体テストの考え方/使い方』をきっかけに古典学派が見直されている流れはありますが、外部APIや決済など副作用の大きい層では今もロンドン学派が現役です。重要なのは「どこに使うか」であり、レイヤーごとに使い分けるのが2026年現在のベストプラクティスです。

デトロイト学派と古典学派は同じものですか

はい、ほぼ同義で扱われます。古典学派は別名「デトロイト学派」と呼ばれ、Kent Beckが提唱したxUnit由来のアプローチを指します。一方ロンドン学派はSteve FreemanらのGOOS本(『実践テスト駆動開発』)に代表される思想で、地名は提唱者・コミュニティの拠点に由来します。

モックとスタブの使い分けはどう判断すればいい?

「呼び出されたかを検証したい」ならモック、「ただ値を返すだけでよい」ならスタブです。古典学派ではテスト対象の外側(DB・外部API)に対してスタブ/Fakeを使い、ロンドン学派ではモックで呼び出し回数や引数を検証します。判断に迷ったら、まずスタブで書いてみて、検証したい振る舞いがあれば初めてモックへ昇格させると過剰モック化を防げます。

TDDではどちらの学派が向いていますか

TDDのスタイルによります。Outside-In TDD(外側から内側へ書く)はロンドン学派と相性が良く、Inside-Out TDD(ドメインから書く)は古典学派と相性が良いです。要件が固まっていない初期はOutside-Inで全体像を捉え、ドメインが明確になったらInside-Outで深く掘る、という併用も実務では機能します。

まとめ

この記事のポイントをまとめます。

  • 単体テストはプログラムの最小単位が正しく動くか確認するプロセス
  • 「単体」の定義は「クラス単位」と「振る舞い単位」の2つの解釈がある
  • ロンドン学派: 依存をすべてモックに置き換え、テスト対象を完全に孤立させる
  • 古典学派: 可能な限り本物のオブジェクトを使い、状態検証をメインに据える
  • ロンドン学派はバグ原因が明確だが、実装詳細に依存しやすく壊れやすい
  • 古典学派はリファクタリング耐性が高く、テストコードが読みやすい
  • 基本は古典学派で進め、外部連携が複雑な箇所だけロンドン学派を使うのが現実的

リファクタリングのたびに壊れるテストがあれば、古典学派のアプローチを試してみてください。

  • この記事を書いた人
  • 最新記事

トム

・都内自社開発企業勤務/Javaバックエンドエンジニア
/Java歴10年以上 ・首都圏在住30代
・資格:基本情報技術者/応用情報技術者/Java Silver/Python3エンジニア認定基礎 詳細なプロフィール

-IT全般