Abstract
JUnit CDI Extensions Core は,JUnit4 で CDI を利用したテストを行うための基本機能を提供します.
テストクラスで CDI を利用するには,
@RunWith
アノテーションに
org.seasar.junitcdi.core.runner.CDI
クラスを指定します.
@RunWith(CDI.class) public class XxxTest { ... }
これにより,CDI コンテナが準備されます.
JUnit CDI Extensions では,テストクラス自体も CDI で管理されます.
そのため,テストクラスの
.class
ファイルが作成されるディレクトリには
META-INF/beans.xml
ファイルが必要です.
Maven2 のディレクトリ構成であれば,
src/test/resources/META-INF/beans.xml
を作成します.
ファイルの内容は以下のようにルート要素だけで構いません. 詳細は CDI の仕様書を参照してください.
<bean></bean>
Injection
テストクラスも CDI で管理されるため,通常の bean と同じように
@Inject
アノテーションにより bean が注入されます.
@RunWith(CDI.class) public class XxxTest { @Inject XxxBean xxx; ... }
Contexts
JUnit CDI Extensions では,CDI 標準のコンテキスト (スコープ) を利用することができます.
@ApplicationScoped
@Session
@Scoped
@Singleton
@Default
(デフォルト)
いずれのコンテキストもテストメソッドを実行している間だけ有効で, テストメソッドの実行が終了するとコンテキストはクリアされます.
TestClassScoped
JUnit CDI Extensions は,同じテストクラスの複数のメソッドを実行している間有効な, 独自の「テストクラス・スコープ」を提供します.
「テストクラス・スコープ」を使うには,bean に
org.seasar.junitcdi.core.TestClassScoped
アノテーションを指定します.
以下の例では,テストメソッド
hoge()
および
moge()
の実行時,フィールド
xxx
には同じ bean が注入されます.
@TestClassScoped public class XxxBean { ... } @RunWith(CDI.class) public class XxxTest { @Inject XxxBean xxx; @Test public void hoge() { ... } @Test public void moge() { ... } ... }
テストクラスをまたがったスコープは提供されません.
Lifecycle Methods
JUnit4 Lifecycle Methods
JUnit CDI Extensions は,JUnit4 標準のライフサイクルメソッドに加えて, 特定のテストメソッドの前後に呼び出されるライフサイクルメソッドを提供します.
特定のテストメソッドの前に呼び出されるメソッドには,
org.seasar.junitcdi.core.BeforeMethod
アノテーションを,後に呼び出されるメソッドには
org.seasar.junitcdi.core.AfterMethod
を指定します.
以下の例では,
beforeHoge()
メソッドは
hoge()
メソッドが実行される前に,
afterHoge()
メソッドは
hoge()
メソッドが実行された後に呼び出されます.
@RunWith(CDI.class) public class XxxTest { @BeforeMethod public void beforeFoo() { ... } @Test public void foo() { ... } @AfterMethod public void afterFoo() { ... } ... }
デフォルトでは,ライフサイクルメソッドの名前から
before/after
を取り除いて先頭を小文字にした名前のテストメソッドが対象となります.
アノテーションで対象となるテストメソッドを (複数) 明示することも出来ます.
以下の例では,
before()
メソッドは
hoge()
および
moge()
メソッドが実行される前に呼び出されます.
@RunWith(CDI.class) public class XxxTest { @BeforeMethod({"hoge", "moge"}) public void before() { ... } @Test public void hoge() { ... } @Test public void moge() { ... } ... }
CDI Lifecycle Methods
テストクラスも CDI で管理されるため,通常の bean と同じように CDI のライフサイクルメソッドを持つことが出来ます.
以下の例では,テストクラスのインスタンスが作成されて DI が終了した後に
hoge()
メソッドが,テストが終了してテストクラスのインスタンスが破棄される際に
moge()
メソッドが呼び出されます.
@RunWith(CDI.class) public class XxxTest { @PostConstruct public void hoge() { ... } @PreDestroy public void moge() { ... } ... }
Events
JUnitの
org.junit.runner.notification.RunListener
による通知を,CDI のイベントとして任意の bean で受信することが出来ます.
public class XxxBean { public void onTestStarted(@Observes @TestStarted Description description) { ... } ... }
サポートされる通知と対応するアノテーションおよびパラメータの型は以下の通りです.
JUnitの通知 | アノテーション | イベントの型 |
---|---|---|
testStarted(Description) |
org.seasar.junitcdi.core.event.TestStarted |
org.junit.runner.Description |
testFinished(Description) |
org.seasar.junitcdi.core.event.TestFinished |
org.junit.runner.Description |
testFailure(Failure) |
org.seasar.junitcdi.core.event.TestFailure |
org.junit.runner.notification.Failure |
testAssumptionFailure(Failure) |
org.seasar.junitcdi.core.event.TestAssumptionFailure
|
org.junit.runner.notification.Failure |
testIgnored(Description) |
org.seasar.junitcdi.core.event.TestIgnored |
org.junit.runner.Description |
testRunStarted(Description)
および
testRunFinished(Result)
はサポートされません.
JUnit CDI Extensions 独自のイベントもあります.
イベントの型はいずれも
org.seasar.junitcdi.core.event.TestInfo
です.
アノテーション | イベントが発生するタイミング |
---|---|
org.seasar.junitcdi.core.event.TestMethodStarted |
テストメソッドが呼び出される直前 |
org.seasar.junitcdi.core.event.TestMethodFinished |
テストメソッドが呼び出された直後 |
以下の例では,テストメソッドが呼び出される直前に
onTestMethodStarted()
メソッドが呼び出されます.
public class XxxBean { public void onTestMethodStarted(@Observes @TestMethodStarted TestInfo testInfo) { ... } ... }
テストメソッドに
Qualifier
が指定されると,それがイベントにも反映されます.
以下の例では,
hoge()
メソッドのように
@Hoge
で注釈されたテストが実行される前にだけ
XxxBean
クラスの
onHogeStarted()
メソッドが呼び出されます.
@Qualifier @Target( { METHOD, PARAMETER }) @Retention(RUNTIME) public @interface Hoge { } @RunWith(CDI.class) public class XxxTest { @Test @Hoge public void hoge() { ... } ... } public class XxxBean { public void onHogeStarted(@Observes @TestStarted @Hoge Description description) { ... } ... }
テストが正常に実行される際の, ライフサイクルメソッドおよび,
RunListener
イベントと JUnit CDI Extensions 独自のイベントが発生する順序関係は以下のようになります.
ライフサイクルメソッド | RunListener
イベント
|
独自イベント |
---|---|---|
@BeforeClass |
|
|
|
@TestStarted |
|
@Before |
|
|
@BeforeMethod |
|
|
|
|
@TestMethodStarted |
@Test |
|
|
|
|
@TestMethodFinished |
@AfterMethod |
|
|
@After |
|
|
|
@TestFinished |
|
@AfterClass |
|
|
JNDI
JUnit CDI Extensions は,JNDI 経由で CDI コンテナから bean をルックアップする
javax.naming.Context
を提供します.
これにより,JNDI でルックアップされるコンポーネントや
@Resource
アノテーションで DI されるコンポーネントを bean として用意しておくこくことができます.
この JNDI
Context
を利用するには,クラスパスに
jndi.properties
ファイルを作成して以下の内容を記述します.
java.naming.factory.initial=org.seasar.junitcdi.core.internal.JndiContextFactory
これで
InitialContext
を利用して CDI コンテナから bean をルックアップすることができます.
DataSource ds = InitialContext.doLookup("java:comp/env/jdbc/DataSource");
あるいは,上記の内容をもった
Hashtable
を作成して
InitialContext
を作成します.
Hashtable<Object, Object> env = new Hashtable<Object, Object>(); env.put(Context.INITIAL_CONTEXT_FACTORY, "org.seasar.junitcdi.core.internal.JndiContextFactory"); Context ctx = new InitialContext(env); DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/DataSource");