Humble Objectパターンとは

Humble Objectパターンはソフトウェアのデザインパターンの1つ。 Humble Objectパターンを用いることで、ユニットテストが書きやすくなる。

Humbleは「控えめ」という意味で、テストしにくいロジックとテストしやすいロジックを分離し、テストにくいロジックが控えめになるよう分割すべきというものになる。

Humble Objectパターンの対象となるもの

Humble Objectパターンの適用が必要なものを考えてみる。

GUI。一般的にGUIに関する処理はテストがしにくい。iOSアプリ開発で言えば、UIKitに依存した処理はテストがしにくい。この場合は、UIKitに依存する処理をViewに該当するクラスに寄せ、UIKitに依存しない処理をPresenterViewModelに寄せる。例えば特定条件の場合に文字を赤くするような処理の場合には、UILabelのUIColorの値を出力として検証するのではなく、ViewModelに定義したlet isRed: Boolのような値を出力としてViewModelをテスト対象にする。

生成処理が隠蔽されているもの。フレームワークで定義されたクラスでイニシャライザ(コンストラクタ)が隠蔽されている場合などは、そのオブジェクトを生成することができないため、ユニットテストがしにくい。例えばiOSのUICollectionViewCellはインスタンスの再利用を前提とされている。

データストア。データベースアクセス、通信処理を伴うものはAPI側の状態や通信時間にユニットテストが影響されるため、ユニットテストがしにくい。HTTP通信をスタブするライブラリを利用するという手もあるが、データストアに関する処理は適切に抽象化し、テスト時はモック化することが好ましい。

Humble Objectパターンの要点

プロダクトのテストカバレッジを100%にするというのは、技術的にも費用対効果的にも現実的ではない。そのため、テストすべき領域とテストしなくても良い領域をまずプロダクト全体で定義する。

その上で、テストすべきとした領域のテストカバレッジを上げていくのが効率が良い。

また、テスト対象領域をプロダクトで定義した場合、逆にテスト対象でない領域にロジックを書いてしまう力学が働く。この場合はテスト対象でない領域がHumble ObjectになるようコードレビューやLinterなどで指摘していく必要がある。

Humble Objectパターンの副次効果

Humble Objectパターンを利用することで、特定のフレームワークに依存した処理以外のコアとなるロジックが自然と集約される。例えば、iOSのUIKitやmacOSアプリのAppKitに依存する処理と、アプリケーション本来のフレームワークに依存しない処理が分離されるため、それぞれに対してユニットテストを書く必要がなくなりモジュールの再利用性が高まる。

参考書籍