Hatena::ブログ(Diary)

裏紙

 | 

2011-09-20

JUnit 4.9の@ClassRuleでクラス単位の前後処理

| 01:07

というわけで先日JUnit 4.9がリリースされたようです。ぶっちゃけリリースされたことに全然気付かんかったです。

今回の目玉は@ClassRuleっぽい? 4.8系にあった@Ruleのクラス版ですね。@Ruleは@Beforeと@Afterのような前後処理の代替は勿論、もっと柔軟に共通処理を定義出来ました。@ClassRuleは@BeforeClassと@AfterClassの代替となるアノテーションのようです。public staticなTestRule型のフィールドに注釈します。

ちょろーんとサンプル書いてみました。

package sample;

import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;

public class TestRuleSample {

    static class MethodRuleSample implements TestRule {

        @Override
        public Statement apply(final Statement base,
                final Description description) {
            return new PrintlnStatement(description.getMethodName(), base);
        }
    }

    static class ClassRuleSample implements TestRule {

        @Override
        public Statement apply(final Statement base,
                final Description description) {
            return new PrintlnStatement(description.getClassName(), base);
        }

    }

    static class PrintlnStatement extends Statement {

        private final String name;

        private final Statement base;

        public PrintlnStatement(String name, Statement base) {
            this.name = name;
            this.base = base;
        }

        @Override
        public void evaluate() throws Throwable {
            System.out.println("started: " + name);
            base.evaluate();
            System.out.println("finished: " + name);
        }
    }

    @ClassRule
    public static TestRule classRule = new ClassRuleSample();

    @Rule
    public TestRule methodRule = new MethodRuleSample();

    @Test
    public void test_1() throws Exception {
        System.out.println("test_1");
    }

    @Test
    public void test_2() throws Exception {
        System.out.println("test_2");
    }

}

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

started: sample.TestRuleSample
started: test_1
test_1
finished: test_1
started: test_2
test_2
finished: test_2
finished: sample.TestRuleSample

あ、ちなみに今回から@Ruleでお世話になったMethodRuleは非推奨となりました。これからはTestRuleを使いましょー。

@ClassRuleはテストスイートでも役立つようです。例えば次のようなテストスイートだとまとめられた全てのテストの実行が5秒以内に終わらないとテスト失敗になります。


package sample;

import org.junit.ClassRule;
import org.junit.rules.Timeout;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;

@RunWith(Suite.class)
@SuiteClasses({ Sample1.class, Sample2.class })
public class TestSuiteSample {

    @ClassRule
    public static Timeout timeout = new Timeout(5000);

}
 |