2011年3月20日日曜日

取得したクラスがあるインターフェースの実装であることを調べるJUnit4のテスト方法

BuilderFactoryパターンを実装する場合、取得されるクラスが想定通りのクラスであるかをテストしたくなります。
その場合に役立つのがJUnit4のIsInstanceOfです。


たとえば、社員(Staff)インターフェースを実装した二つのクラス(SalesStaffとServiceStaff)があって、それらを取得するためのBuilderFactoryパターンを作ったとします。


…ちなみにデザインパターンの本は持っているけど、詳しくは知らないから、その辺勘弁ね。
…あと、UMLとか書き方知らんので、その辺も勘弁ね。


// Factoryを作る
  StaffFactory factory = new StaffFactory();

  // SalesStaffをインスタンス化
  Staff sales = factory.getInstance("Sales");

  // ServiceStaffをインスタンス化
  Staff service = factory.getInstance("Service");


で、このFactoryのテストを書くとしましょう。

単純には、JUnit3のままでやると、こんな感じのテストになるでしょう。

public class FactoryTest extends TestCase {

  public void testGetInstance(){
    // Test1 : SalesStaffを取得できているかテストする。
    assertTrue( factory.getInstance("Sales")
        instanceof SalesStaff);

    // Test2 : ServiceStaffを取得できているかテストする。
    assertTrue( ServiceStaff.class.isInstance(
        factory.getInstance("Service")) );
  }
}


う~ん、微妙…

Test1のケースは、instanceofという演算子が気にくわないですね。
instanceofはClass同士の関係性について調べるものだから、演算子ではないような気がするんです。
むしろClassObjectのメソッドであるべきだと思うわけですよ。

で、一応Classには、#isInstance(java.lang.Object)というメソッドがあって、それを使ったのがTest2
美しくね~な。
何が美しくないって、Class isInstance Objectって、英語のシンタックスにあっていないのが非常に美しくないのですよ。
Object isInstanceOf Classという形にしたい。

まあ、そこでJUnit4に登場願いますのですよ。
JUnit4で同じようなテストを書くと、次のような感じ。


import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

public class FactoryTest {
  @Test
  public void testGetInstance() {
    // Test3 : SalesStaffを取得できているかJUnit4でテストする。
    assertThat( factory.getInstance("Sales"),
      is(instanceOf(SalesStaff.class)));
  }
}


これはナチュラルに英語のシンタックスとあっている。
やはり名前重要!(きのこ本のまつもとゆきひろさんの記事のタイトル)

ちなみに、下記のページを参考にしました。
Android JUnit Testでhamcrestをつかう

0 件のコメント:

コメントを投稿