[JUnit4]Ruleアノテーションを使って共通する処理をまとめる
複数のテストケースで共通の初期化処理があるとき、以下のようにリソースクラスを作って、各テストクラスでセットアップメソッドを呼んでいた
・共通するリソースクラス
public class DatabaseConnectionResource{ private SessionFactory sessionFactory; public void setUp(){ sessionFactory = createSessionFactory(); } public void tearDown(){ sessionFactory.close(); } }
・テストクラス
public class HogeTest{ private static DatabaseConnectionResource connection; @BeforeClass public static void setUp(){ connection = new DatabaseConnectionResource(); connection.setUp(); } @AfterClass public statis void tearDown(){ connection.tearDown(); } }
これをJUnit4のRuleアノテーションを使うともっと簡潔に書けるようになる。
・共通するリソースクラス
public class DatabaseConnectionResource extends ExternalResource{ private SessionFactory sessionFactory; @Override protected void before() { sessionFactory = createSessionFactory(); } @Override protected void after() { sessionFactory.close(); } }
・テストクラス
public class HogeTest{ @ClassRule public static DatabaseConnectionResource connection = new DatabaseConnectionResource(); }
ClassRuleアノテーションを付けると、@BeforeClass、@AfterClassのタイミングでそのオブジェクトの対応メソッドが呼ばれる。
また、ClassRuleを付けたフィールドは可視性がpublicでなければならない。(そうでないと実行時に怒られる)
@Before、@Afterに対応する場合は@ClassRuleではなく、Ruleアノテーションが利用できる。
また、複数のRuleがある場合はその実行順序は定義されないが、RuleChainを使ってインスタンスを生成することで、指定した順序で呼ばれるようになる。
//outer、innerの順でbeforeメソッドが呼ばれ、その逆順でafterメソッドが呼ばれる @Rule public RuleChain ruleChain = RuleChain.outerRule(new ExternalResourceOuter()).around(new ExternalResourceInner());
なお、@ClassRuleはJUnit4.9から、RuleChainはJUnit4.10から追加された機能となる。