JUnit4への対応

S2EJB3UnitをJUnit4に対応させようとあれこれ考えていたら、S2FrameworkTestCaseやS2TestCaseもJUnit4に対応できそうだと気づきました。
こんな感じはどうでしょうか?

テストクラス

import javax.transaction.Status;
import javax.transaction.TransactionManager;

import junit.framework.JUnit4TestAdapter;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.seasar.extension.unit.S2TestCase;
import org.seasar.framework.unit.S2TestClassRunner;
import org.seasar.framework.unit.annotation.AfterMethod;
import org.seasar.framework.unit.annotation.BeforeMethod;
import org.seasar.framework.unit.annotation.Rollback;

@RunWith(S2TestClassRunner.class)
public class HogeTest extends S2TestCase {

  TransactionManager tm;

  public static junit.framework.Test suite() {
    return new JUnit4TestAdapter(HogeTest.class);
  }

  @Before
  public void before() throws Exception {
    include("j2ee.dicon");
    System.out.println("before");
  }

  @After
  public void after() {
    System.out.println("after");
  }

  @Test 
  @Rollback
  @BeforeMethod("hoge") 
  @AfterMethod("foo")
  public void rollbackTest() throws Exception {
    System.out.println("rollbackTest");
    assertTrue(tm.getStatus() != Status.STATUS_NO_TRANSACTION);
  }

  public void hoge() {
    System.out.println("hoge");
  }

  public void foo() {
    System.out.println("foo");
  }
  
}

実行結果

before
hoge
DEBUG 2006-04-01 19:54:50,409 [org.seasar.framework.log.Logger] トランザクションを開始しました
rollbackTest
DEBUG 2006-04-01 19:54:50,419 [org.seasar.framework.log.Logger] トランザクションロールバックしました
foo
after


JUnit4はTestCaseを継承しなくてもOKなところが特徴みたいですが、S2TestCaseには有用なメソッドがたくさんあるのでJUnit4に対応するといっても継承しないわけにはいかないなぁと思いました。

JUnit4を使うためのポイントは

  • RunWithアノテーションでS2TestClassRunner.classを指定する。(指定しなければJUnit3を使った場合と同じ挙動になる)
  • S2FrameworkTestCaseかそのサブタイプ(S2TestCaseとか)を継承する。(継承しない場合はJUnit4を素で使った場合と同じ挙動になる)
  • Eclipseで実行するにはJUnit4TestAdapterを使う(らしい)。


JUnit4に対応してうれしいことは

  • JUnit4のアノテーション(@Test、@BeforeClass、@AfterClass、@Before、@After、@Ignore)が使える。
  • @Rollbackを使用してトランザクション制御が行える。これまでのtestXxxTxメソッドに相当。
  • @BeforeMetohdでテストメソッド実行前に行いたい処理を記述できる。これまでのsetUpXxxに相当。
  • @AfterMetohdでテストメソッド実行後に行いたい処理を記述できる。これまでのtearDownXxxに相当。


JUnit4を使った場合の注意点は

  • testXxxTxやsetUpXxxやtearDownXxxに特別な意味はなくなる。通常のメソッドと同じ扱い。(JUnit4でsetUpメソッドやtestXxxメソッドに特別な意味がなくなっているのでそれにならいました)
  • 次のメソッドをテストクラスでオーバーライドしても振る舞いが変わらない。(実行されないので)
    • TestCaseクラスのメソッド
    • S2FrameworkTestCase.doRunTest
    • S2FrameworkTestCase.runBare
    • S2FrameworkTestCase.setUpForEachTestMethod
    • S2FrameworkTestCase.tearDownForEachTestMethod
    • S2TestCase.doRunTest
    • S2TestCase.needTransaction
  • (setUpAfterContainerInitとかsetUpContainerなど上記以外のメソッドのオーバライドは有効です。)


じつはコミットしてしまったのですけど、org.seasar.framework.unitにクラスを追加してよかったでしょうか?