なんとかするから、なんとかなる

エンジニア関係のことを書きます

レガシーコード改善を読んで

クラスをテストにしやすくするには

 

1. クラス間の依存性を下げる。

2. 他のクラスを使用する場合、そのやりとりをプロトコルで定義することで、テスト用のモックと振替可能にする。

 

1. クラス間の依存性を下げる

クラスをテストする上で、大変になってくるのは、テスト対象のクラスを個別で生成•使用することが難しくなこと。

あるクラスが他のクラスを参照している場合、そのクラスをテストするためには他のクラスも生成しなければならない。他のクラスもまた別のクラスを参照するとかになると、どんどん話はややこしくなっていく。

では、どうするのか。

一番良いのはクラスが他のクラスに依存しなくても成立するようにすることだ。しかし、それが困難な場合もある。

その場合、必要に応じて他のクラスの情報を渡すのが良いだろう。インスタンス生成時のイニシャライザやメソッドの引数にその情報を渡すのだ。

引数と渡すとこで、テスト時にはその引数をテスト用クラスに差し替えることが可能となる。

 

2. 他のクラスとのやりとりをプロトコルで定義する。

1. の話の続きとして、1.では引数で他のクラスとの依存性注入すると書いた。

今度は、依存される側のクラスをテストクラスに差し替えることを考えよう。

依存される側とクラスをどうやって、テストクラスに差し替えるか。

そこで利用するのがプロトコルである。プロトコルで、依存する側が必要とする処理を定義しておき、依存される側がそのプロトコルに則って実装する。

こうすることで、依存される側をテストクラスに差し替える場合、プロトコルで定義されたメソッドのみをテスト用に書くだけで良い。

後は、イニシャライザやメソッドの引数としてテスト用クラスを渡すことで、テストを実施することができる。

 

追記(2017/4/22)

イニシャライザの引数にすべてのクラスを渡すのは困難。

渡されるクラスがないと、生成されるクラスが存在できない場合、依存が高い場合はイニシャライザの引数として渡す。

クラス生成後に状態のように後から別のクラスをSetする場合は、イニシャライザで渡したり、メンバ変数に参照を渡すよりも、setメソッドを定義したほうがよさそう。

テスト時もsetメソッドにダミーのテストを渡せるように。

メンバ変数を直接いじるは、カプセル化的にもよくない。

もちろん、setメソッドではプロトコルでsetできるようにしておくのがベスト。

 

 

レガシーコード改善ガイド (Object Oriented SELECTION)

レガシーコード改善ガイド (Object Oriented SELECTION)