「JUnitでユニットテストをするときに、クラス間の関係が問題でテストできない。」なんて事ありませんか? TDD(テスト駆動開発)で行っている場合は、クラスの関係をそのつど考えながら進めていくので、こういった問題はあまり起きません。しかし、TDDはまだまだ敷居が高いと思う開発者が多いように思います。

テスト駆動開発考察

djUnit を使うと、JCoverage』というツールを使ったカバレッジテストの結果をエディタ上で見ることが出来るようになります。

djUnitは JUnti の機能と Aspect の機能を併せ持ったユニットテストツールとなっています。

参考

djUnit Wiki

解説

JUnitの問題とは?

JUnitでユニットテストを行うときに問題となる「クラス間の関係」は、Mock Object(モックオブジェクト)を使ってテストするというのが通例になっているようです。しかし、この Mock Object も、クラス設計によっては使えない場合が多いのです。

例えば、クラスの内部で他のクラスに依存している場合などは、外側(テストケース側)からMock Object を注入することが出来ません。そのため、最近話題の DI(依存性注入)を使ってテストケースを組み立てることが不可能になります。

djUnitを使うとどうなるのか

djUnitは Eclipse のプラグインとして動作する、ユニットテストツールです。JUnitよりも簡単にユニットテストを行うことが出来るようになります。最新版ではAntのタスクとして使うことも出来るようになっています。

djUnitを使うと、Virtual Mock Objects という手法を用いて、クラス内部の処理をAspect技術を使って切り替えることが出来てしまいます。例えばテストしたいメソッドの内部で、リソースファイルに依存した処理があるとします。

public String getProperty(String key, String defaultValue) {
  ResourceBundle resource = 
        ResourceBundle.getBundle("config.properties");
  if (resource == null) {
    return defaultValue;
  }
 
  String val = resource.getString(key);
  if (val == null || "".equals(val)) {
    return defaultValue;
  } else {
    return val;
  }
}

この例では、リソースバンドルを外部から取得しているため外部に依存してしまっています。つまり、ユニットテストがしにくいのです。本来なら、Mock Object を使って、ResourceBundle を擬似クラスで模倣してテストするのですが、それにはメソッドをリファクタリングする必要がでてきます。

Virtual Mock Objects を使うと、メソッドはそのままで、ResourceBundle#getBundle の戻り値だけを Mock Object に変更することが出来ます。また、ResourceBundle#getString も戻り値も好きなものに変更することもできます

参考

Virtual Mock Objects とは? djWiki

djUnitの使い方

djUnitの詳しい使い方は、『Virtual Mock Objects を使ったテスト』を参考にしてください。非常に詳しく書いてあります。一度つかったら、Virtual Mock Objects の使いやすさを実感できると思います。

djUnitのもう一つの利点としては、カバレッジテストレポートが出力できる点です。djUnit は Eclipse の Plugin として提供されているので統合環境上でカバレッジテストの結果が見えるのはかなり便利です。どの処理がテストされていないかをエディター上に表示してくれる点は、テストケースの抜けを未然に防げるので重宝しそうです。

参考

カバレッジレポートを見る

Virtual Mock Objects の気になるところ

Virtual Mock Objects は非常に簡単に、楽しくユニットテストが実行できる優れたツールだと思います。しかし、いくつか気になる点があります。(個人的にですが・・・)


  • JUnit + Aspect の概念が分からないと、仕組みが理解しづらいかも
  • どんなにクラスの関連が複雑でもとりあえずテストできてしまう
  • リファクタリングでよい設計にしようとする気力が薄れる可能性がある
  • テストケースが失敗したのが、Aspect が問題なのか処理が問題なのか切り分けがつかない場合があるかもしれない
  • JCoverageの結果は参考程度に受け取るべし

テストしづらいプログラムでも何とかなってしまうというのが Virtual Mock Objects の気になるところではありますが、カバレッジツールを使うだけでも djUnit を使う価値はあるかと思います(他に良いカバレッジツールがあればdjUnitは不要なのか???・・・)。通常はJUnitの代わりとして使い、どうしてもJUnitではテストが難しい部分や、外部に依存してしまっている部分は Virtual Mock Objects を使うというのがいいのかもしれません。どちらにしても、かなり面白いテストツールだと思います。

参考

  • djUnitを作っているところです。Wiki に非常に詳しく使い方が載っています。 djUnit Wiki

  • 上記と同じサイト内の、Virtual Mock Objects に関するページへのリンクです。 Virtual Mock Objects を使ったテスト(in djUnit Wiki)

  • エクリプスに関する日本語の Wiki サイトです。djUnitの概要が分かりやすく載っています。 エクリプス Wiki

  • Virtual Mock Objects に関するドキュメントです。英文ですが興味深い内容です。 Virtual Mock Objects using AspectJ with JUNIT

  • エクリプス本家へのリンクです。djUnitは Eclipse のプラグインとして動作します。 Eclipse.org

  • JUnitの使い方がたっぷり載っている書籍です。