第4章:接合モデル

はじめに

単体テストのために行わなければいけないこととしてたくさんの依存関係の排除が挙げられる。
いかにして、クラス間の依存関係が排除されている状態を作り出すか、そのための方法のヒントが書かれている。

書籍では以下の例を挙げて説明されている。

■前提
・Initという関数がある。
・その中で、ある条件を満たすとPostReceiveErrorという関数を呼ぶ。
・PostReceiveErrorは別のサブシステムとやり取りするグローバル関数であり、そのサブシステムがテストで非常に扱いにくい。

■問いかけ
テストのときはPostReceiveErrorを呼び出さずにInit関数をテストしたい。
本番ではPostReceiveErrorを呼ぶ必要がある。
どうやってInit関数をテストする?

接合部と許容点

■接合部(Seam
その場所を直接編集しなくても、プログラムの振る舞いを変えることができる場所。
接合部は、その振る舞いを変更できる場所(許容点)を持つ。

■許容点(Enabling Point)
どのふるまいを使うかを決定する場所。

接合部の種類

よく使われているのはオブジェクト接合部。
リンク接合部とプリプロセッサ接合部はメンテが難しいとのこと。

種類 概要 許容点は何か
リンク接合部 JavaであればCLASSPATHを変更して、同じ名前のクラスだけど、プロダクトコードで呼び出されるパスとテスト時に呼び出されるパスを切り替える。 CLASSPATHmakefileIDEの設定等
プリプロセッサ接合部 CやC++でよく使われる。プリプロセッサを使うことでふるまいを変更する。書籍ではプログラムの振る舞いを再定義したlocaldefs.hというヘッダファイルを作成してそれを該当コードでincludeしていた。 プリプロセッサ定義
オブジェクト接合部 オブジェクト指向の特性を活かしてふるまいを変える。振る舞いを変えたいメソッドを持つAbstractクラスやインタフェースを定義して、抽象に依存させるようにする。抽象を継承した、テスト用に振る舞いを変えたクラスを定義してテスト時にそのオブジェクトを使うようにさせる。こうすることで、「テストコードではこの処理はさせたくないけど、プロダクトコードでは実行させないといけない処理を切り替える」ことができるようになる。 オブジェクトを生成すると決めた場所

まとめ

依存を排除してテストしやすくするための方法として3種類の接合部がある。
そのなかでよく使われているのはオブジェクト接合部。
抽象に依存させ、振る舞いを変えたいメソッド定義を上書きした具象クラスを用意する。

テストのときは、振る舞いを上書きした具象クラスへの依存をさしこむことで、この章での問いかけである「テストのときは "事情によりテストしたくない関数" を呼び出さずに "テスト対象の関数" をテストしたい。本番では "事情によりテストしたくない関数" を呼ぶ必要がある。どうやって "テスト対象の関数" をテストする?」を実現する。

「メソッドに振る舞いを変える」という点では3章と似ているが、3章との違いは以下のような認識。

3章:振る舞いを変えることで、外から見えない、オブジェクトが持っている状態が正しいかを確認する。

4章:振る舞いを変えることで、テスト対象のメソッドに含まれる特定の処理を、テストの時だけ実行させずにテスト対象のメソッドをテストする。

参考

  1. https://iwasiman.hatenablog.com/entry/2018/02/20/200000#%E7%AC%AC4%E7%AB%A0%E6%8E%A5%E5%90%88%E3%83%A2%E3%83%87%E3%83%AB
  2. https://yuyubu.hatenablog.com/entry/2017/07/13/010029
  3. https://twop.agile.esm.co.jp/important-terms-of-regacycode-improvements-133bed5c4f30