Monday, April 26, 2010

UnitTestしやすいクラスの作り方

以下の要約。
http://misko.hevery.com/2008/07/08/how-to-think-about-the-new-operator/

Unit Test しやすいクラスは、クラス間の依存グラフにおいて、 終端に位置するクラス(以下、leafクラス)である。 なぜなら、それだけを Unit Test することができるから。 例えば、以下のようなクラス。

 
class House {
  private boolean isLocked;

  private boolean isLocked() {
    return isLocked;
  }

  private boolean lock() {
    isLocked = true;
  }
}

しかし、以下のようなクラスでは、Kitchenクラスを生成せずに、 House クラスだけを生成できない。 理由は、House のロジック内に、Kitchen の new 演算子が 含まれているから。 そのため、House クラスのみを Unit Test することができない。

 
class House {
  private final Kitchen kitchen = new Kitchen();
  private boolean isLocked;

  private boolean isLocked() {
    return isLocked;
  }

  private boolean lock() {
    kitchen.lock();
    isLocked = true;
  }
}

Houseだけを個別に Unit Test するには、偽の Kitchen で、Houseを生成する必要がある。

 
class House {
  private final Kitchen kitchen;
  private boolean isLocked;

   public House(Kitchen kitchen) {
    this.kitchen = kitchen;
  }

  private boolean isLocked() {
    return isLocked;
  }

  private boolean lock() {
    kitchen.lock();
    isLocked = true;
  }
}

上のように、new演算子をロジックから取り除けば、 テストを簡単に行える。 Kitchen のモックを作れば、Houseだけを Unit Test できる。 これにより、leaf クラスでなくても、個別にテストを行える。

どこで、new演算子を使えばいいかというと、 以下のようにFactoryクラスを作ってやればよい。

 
class ApplicationBuilder {
  House build() {
    return new House(new Kitchen(
               new Sink(),
               new Dishwasher(),
               new Refrigerator())
           );
  }
}

Main メソッドでは、このFactoryを使ってオブジェクトの依存関係を 生成すればよい。

 
class Main {
  public static void main(String...args) {
    House house = new ApplicationBuilder().build();
    house.lock();
  }
}

No comments:

Post a Comment