JUnit4.5以降の拡張方法

以前に書いたJUnit4の拡張方法に関してコメントにて質問があったので4.5以降のバージョンを書いておきます。せっかくコメント頂いたのに全然気づかずに無視したみたいな形になって申し訳ありませんm(_ _)m

まず、やりたいことの前提として「テストクラス内において特定のテストケースのみで事前処理や共通チェックを行いたい」と言った場合に、どこらへんを拡張すればよいかを以前書きました。しかし、JUnit4.5からはJUnit4ClassRunnerは非推奨になり4.8.2時点ではクラスも削除されています。なので4.8.2ベースでエントリーし直しをしてみます。

まず、独自のアノテーションを作成します。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
}

次に実行時にアノテーションの判定やら独自の処理やらを実行するクラスとしてorg.junit.runners.model.Statementを継承して作成します。
やってることは基本的に前回のエントリーと変わりません。

public class MyStatement extends Statement{
	private final FrameworkMethod testMethod;
	private final Object target;

	public MyStatement(FrameworkMethod testMethod,Object target) {
		this.testMethod = testMethod;
		this.target = target;
	}

	@Override
	public void evaluate() throws Throwable {
		if(testMethod.getAnnotation(MyAnnotation.class) != null){
			System.out.println("アノテーション発見!");
		}
		testMethod.invokeExplosively(target);
	}
}

次に、上記で作成したStatementを使用する独自のRunnerを作成します。
継承元はJUnit4ClassRunnerからBlockJUnit4ClassRunnerに変更です。

public class MyTestRunner extends BlockJUnit4ClassRunner{
	public MyTestRunner(Class<?> klass) throws InitializationError {
		super(klass);
	}

	@Override
	protected Statement methodInvoker(FrameworkMethod method, Object test) {
		return new MyStatement(method, test);
	}
}


上記を元にテストを書いてみます。

@RunWith(MyTestRunner.class)
public class MyTestRunnerTest {

	@Before
	public void before(){
		System.out.println("-- before --");
	}
	
	@Test
	public void testA(){
		System.out.println(" testA ");
	}
	
	@MyAnnotation
	@Test
	public void testB(){
		System.out.println(" testB ");
	}
}

上記を実行するとコンソールには下記のように表示されます。

-- before --
 testA 
-- before --
アノテーション発見!
 testB 

と言う具合で拡張出来るのですが、@Ruleとかを駆使したいするのがホントはいいんだろうかとも思います。まだ@Ruleの使用方法は把握しきれてないので後日エントリーを書こうと思います。(でも、publicフィールドってのが個人的に気に入らないんですけどねぇ)