/note/tech
- DDDにおけるユースケースやサービスなどに分類されるモジュールはその性質上トランザクションスクリプトになりやすい
- それ自体はある程度仕方がない
- とはいえ、トランザクションスクリプト化したコードのユニットテストはかなり苦痛である
- 何故なら単純にコード量が多くなるから
- コード量が多くなるという事は抱える責務も多くなるから
- 適度に関数化して処理を分離したとしても全体で2000行近くに達することはザラである
- このようなコードはユニットテストを書くことがかなり苦痛である(二度目)
- その理由は、後半のコードをテストする為には前半のコードをパスするようモックなりテストフィクスチャなりを構成する必要があるからである
- また、コードが多い分、テストパターンも増加する
- 増加したテストパターン分の事前準備コードの作成と保守は控えめに言って悪夢である
- 多くの場合、このようなテストは「とりあえず動けばいい」の精神で作られがちだし、事前準備コードは既存のコピペになり、そのテストケースの目的と整合性が取れないままになっていることが多い
- というか、人間の認知限界を容易に超える
- そのようなテストコードは信頼性が低く、品質にも疑問が残る
- というわけで、ユースケース/サービス的なモジュールは具体的なロジックを書くべきではない
- 具体的なロジックはそれ専用のオブジェクトに処理を委譲するべきである
- ユースケース/サービス的なモジュールは専用オブジェクトの生成・実行・結果受取に専念するべきである
- オブジェクトロールステレオタイプにおける調整役として振る舞うべきである
- 専用オブジェクトをユースケース/サービス的なモジュールのメソッド内で生成しては結局テストが困難になる
- 専用オブジェクトはコンストラクタ・インジェクションするか、ファクトリーオブジェクトを介して生成するのがよい
- 更に言えば、専用オブジェクトの処理結果を保持するオブジェクトもあると良い
- ある処理が前段の処理結果に依存することがあるのはよくある事なので、状態を保持するオブジェクトを持つことでユニットテストを簡単に作成することが可能になる
tag:
(2025/02/17)