2012年8月5日日曜日

JMockit で Hello World をテストファーストしてみよう

main() メソッドから System.out.println("Hello, World!") してるだけのコードをテストファーストで書くとどうなるか?

これを Eclipse と JMockit でやってみる。

====

まず、こんな感じで普通の JUnitコードを書く。

public class HelloWorldTest {
   @Test public void test() {
      HelloWorld.main(new String [0]);
   }
}
この時点では、まだ HelloWorld クラスがないので、Eclipse のエディタ上では、HelloWorld の下に赤い下線が引かれている。そこにカーソルを移動して Ctrl+1 を押下してクラスの生成を選ぶとダイアログが開くので、main 生成にチェックをいれて Finish。こんなクラスが生成される。
public class HelloWorld {
   /**
    * @param args
    */
   public static void main(String[] args) {
      // TODO Auto-generated method stub
   }
}
Eclipse での作業中はショートカットを活用すると無駄なタイピングをかなり削減できる。

コンパイルが通ったところで、一応、テスト実行してグリーンになることを確認しておく。


次に System.out の println メソッドに "Hello, World!"が渡される事を確認する。

これは JMockit を使うので、pom.xml に以下のように追記する。ただし、インストゥルメンテーションの都合上、<dependencies>の中で junit の前に書かれていなくてはならない。

  <dependency>
   <groupId>com.googlecode.jmockit</groupId>
   <artifactId>jmockit</artifactId>
   <version>0.999.15</version>
  </dependency>

テストコードには以下のように追記する。

public class HelloWorldTest {
   @Mocked PrintStream mock;
   @Test public void test() throws Exception {
      new Expectations() {{
         mock.println("Hello, World!");
      }};
      HelloWorld.main(new String[0]);
   }
}

実行してみるとテストが失敗し、以下のような結果がトレースされる。

mockit.internal.MissingInvocation: Missing invocation of:
java.io.PrintStream#println(String x)
with arguments: "Hello, World!"
on mock instance: java.io.PrintStream@15ebf57
・・・
呼ばれるはずのメソッドが呼ばれていないと、JMockit に指摘されている。

ここで main を以下のように書き換えて、再度テスト実行してみる。

   public static void main(String[] args) {
      System.out.println("test");
   }
失敗して、こんなメッセージがトレースされるが、さっきとメッセージが変わっている。
mockit.internal.UnexpectedInvocation: Parameter "x" of java.io.PrintStream#println(String x) expected "Hello, World!", got "test"
・・・
今度は、"Hello, World!" を期待していたのに"test"が渡されたと言っている。

というわけで、おもむろに"test"を"Hello, World!"に書き換えて、テスト再実行。今度はグリーンになる。

実際のテスト・コーディングよりも、敢えてちょっと回りくどい感じでやってみた。

0 件のコメント:

コメントを投稿