はじめに
この記事では、単体テストにおける依存の分類について解説します。用語の定義などは Vladimir Khorikov 氏の単体テストの考え方/使い方(2022, マイナビ出版)に準拠しています。
依存の分類
単体テストにおいて重要な考え方の1つは「依存」の管理です。テストが依存する対象を正しく分類し、管理することで、テストの信頼性を向上させることができます。ここでは、依存を以下のように分類します。
- 共有依存 (Shared Dependency)
- プライベート依存 (Private Dependency)
- プロセス外依存 (Out-of-Process Dependency)
- 揮発性依存 (Volatile Dependency)
1. 共有依存 (Shared Dependency)
定義
テストケース間で共有される依存のことです。同時に実行されるテストが互いに影響を及ぼし、予期しない動作を引き起こす原因となります。
具体例
- 共有データベース: 複数のテストケースが同じデータベースに依存し、テスト中にデータの変更が行われると、他のテストに影響が及ぶ可能性があります。
- ファイルシステム: 一つのテストが特定のファイルを書き換えると、別のテストがその変更に影響を受ける場合があります。
解決方法
- テストごとに独立したデータセットを使用する。
- モックやスタブを利用し、共有リソースへの依存を排除する。
2. プライベート依存 (Private Dependency)
定義
テストケース間で共有されない依存です。プライベート依存はさらに以下の2つに分類されます。
- 可変依存: テストごとに異なる状態や振る舞いを持つ依存。
- 不変依存: どのテストでも状態が変わらない依存。
具体例
-
可変依存: テストごとに異なるパラメータを受け取る関数。
function calculatePrice(discount: number): number { return 100 - discount; }
-
不変依存: 定数や固定値を返す関数。
function getTaxRate(): number { return 10; // 固定の税率 }
重要性
プライベート依存を適切に管理することで、テストの独立性を保つことができます。可変依存ではテストデータを工夫し、不変依存では変更の必要がないことを確認できます。
3. プロセス外依存 (Out-of-Process Dependency)
定義
アプリケーションのプロセス外で稼働する依存です。例えば、異なるプロセス間でデータをやり取りする際に利用されることが一般的です。
具体例
- データベース: SQLクエリを実行する際の依存。
- メッセージキュー: RabbitMQやAmazon SQSなどの外部サービス。
注意点
データベース依存は通常プロセス外依存で共有依存ですが、分離されたテスト用のインメモリデータベースを使用すれば、共有依存を排除できます。
4. 揮発性依存 (Volatile Dependency)
定義
呼び出すたびに異なる振る舞いをする依存や、開発者の環境に特定の設定が必要となる依存のことです。
具体例
- 現在日時
function getCurrentTime(): Date {
return new Date();
}
- ランダム値
function generateRandomNumber(): number {
return Math.random();
}
問題点
揮発性依存はテスト結果を不安定にする可能性があります。テスト実行のたびに異なる結果が得られるため、失敗の原因を特定しづらくなります。
解決方法
- 現在日時やランダム値を返す関数をモックに置き換える。
- 依存を明示的に注入する(例: 現在日時を引数として渡す)。
結論
単体テストを効果的に設計するためには、依存を正しく分類し、影響を最小限に抑える工夫が必要です。特に共有依存や揮発性依存はテストの信頼性に重大な影響を及ぼすため、注意深く管理しましょう。