Junitで見るデザインパターン活用術

前にmixiで書いてたのを公開。

書くことないときに、これ載せます(笑)

さて第一回。

junit-class-diagram
↑保存すると大きくなるよ

junit.frameworkパッケージを見てみよう。
ざっと説明すると、
AssertionFailedErrorから連なる3つのクラスはどうやらテストの結果エラーになったものや例外になったものの情報を保持し、表示させるための文字列を作ったりしているようだ。
TestResult、TestListener、Test、TstCase辺りがコアになるクラスだろう。
Assertは比較を行うユーティリティクラスだ。
assert*()メソッドが定義されている。

今回は手始めにAssertクラスを見ていこう。
ただのユーティリティと侮るなかれ。

みてみると分かるが、ほとんどすべてのメソッドがほかのメソッドに委譲している。
何にも委譲していないメソッドは3つくらいだ。
たとえば、assertFalse()はこのようになっている
static public void assertFalse(String message, boolean condition) {
  assertTrue(message, !condition);
}
ではこのassertTrueはどうなっているか。
static public void assertTrue(String message, boolean condition) {
  if (!condition)
    fail(message);
}
ここでも委譲している。failメソッドはどうなっているだろう。
static public void fail(String message) {
  throw new AssertionFailedError(message);
}
AssertionFailedErrorクラスをthrowしているだけだ。

さて、このassertFalseとassertTrueメソッドを委譲せずに書くとどうなるだろう。
static public void assertFalse(String message, boolean condition) {
  if (condition)
    throw new AssertionFailedError(message);
}
static public void assertTrue(String message, boolean condition) {
  if (!condition)
    throw new AssertionFailedError(message);
}
なんてことだ。「!」がないだけじゃないか。
コードの重複も甚だしい。
しかもassertFalseとassertTrueは対関係にあることが見比べてみて初めて分かる。

適切に委譲することで、コードの重複が避けられ、修正にも強くなる。

と、if文の{}を省略するのはいただけないのであまり倣うべきではないと思う。