backend
B
信頼度ランク
| S | 公式ソース確認済み |
| A | 成功実績多数・失敗例少数 |
| B | 賛否両論 |
| C | 動作未確認・セキュリティリスク高 |
| Z | 個人所感 |
TDD実践: モック過多を防ぐ境界の引き方
外部境界だけをモックし、ドメイン内部は実オブジェクトで検証する。
一言結論
外部境界だけをモックし、ドメイン内部は実オブジェクトで検証する。
背景
外部境界だけをモックし、ドメイン内部は実オブジェクトで検証する。 TDDは儀式ではなく、設計判断を小刻みに検証するための手法です。Mock過剰使用の是正を中心に、実装速度と品質を両立させる現場運用を示します。
TDDの判定軸(網羅)
- Redの明確性: 失敗理由が1つに特定できるか。
- Greenの最小性: 不要な抽象化を避けているか。
- Refactorの安全性: 振る舞いを維持したまま構造改善できるか。
- フィードバック速度: 1サイクルが短時間で回るか。
- 仕様密度: テスト名がドメイン言語を表現しているか。
具体例: 送料計算機能を育てる
- Red:
subtotal=0でshipping=0を失敗で定義。 - Green: 最小if実装で通す。
- Refactor: 送料ルールを関数抽出し命名を改善。
- 次サイクル: 境界値(送料無料閾値、離島加算)を追加。
この順序を守ると、仕様の穴を可視化しながら設計を進められます。
Mock過剰使用の是正で効く深掘りポイント
- テスト粒度: 1テスト1理由を徹底し、複数失敗を混ぜない。
- コミット戦略: Red→Green→Refactorを履歴で追える単位に分割。
- 外部依存管理: DB/API/時刻依存は契約テストへ層分離。
- 失敗分類: Flaky・仕様変更・回帰バグを区別して対応。
- 設計負債管理: リファクタ未実施項目を次サイクルへ残さない。
判断テーブル: Mock/Stub/Realの使い分け
| 対象 | 推奨ダブル | 使う条件 | 注意点 |
|---|---|---|---|
| 外部API | Stub | 応答固定で振る舞い検証 | 契約乖離を別テストで補う |
| メール送信 | Fake | 副作用確認が必要 | 実送信にしない |
| DB | Real + 軽量環境 | SQL/トランザクション確認 | テスト速度とのバランス |
| 時刻/乱数 | Mock/Inject | 決定性が必要 | 実装と契約のズレに注意 |
ニッチ実務ノート
- Approval testingはUI断片/JSON比較で強いが、差分ノイズ抑制(正規化)が鍵。
- Property-based testingは境界値テストの代替ではなく補完。
- Legacy改修では先にcharacterization testを置くと仕様誤解を防げる。
- Outside-inはAPI契約が不安定な初期段階で特に有効。
よくある失敗と対処
- 失敗: Greenで将来要件まで先回り実装。
対処: 「今の失敗を通す最小コード」へ戻す。 - 失敗: テストが遅くサイクルが止まる。
対処: I/O依存を層分離し、速いテストを主回路にする。 - 失敗: リファクタを後回し。
対処: Green直後に3分だけでも命名・重複排除を実施。
チーム導入チェックリスト
- PRでRed→Green→Refactorの意図が追跡できる
- テスト失敗の分類ルール(flake/spec/regression)がある
- ドメイン用語がテスト名に反映されている
- 週次で不要Mock削減とテスト速度改善を実施
- 仕様変更時に既存テストの意味を見直している
まとめ
TDD実践: モック過多を防ぐ境界の引き方 の本質は、設計判断の可視化と学習速度の最大化です。短いサイクルで根拠ある変更を積み上げることで、品質と開発速度の両立が可能になります。