web-dev-qa-db-ja.com

JUnitテストクラス全体でSpringアプリケーションコンテキストを再利用する

多数のJUnitテストケース(統合テスト)があり、それらは論理的に異なるテストクラスにグループ化されています。

http://static.springsource.org/spring/docs/current/springに記載されているように、Springアプリケーションコンテキストをテストクラスごとに1回読み込み、JUnitテストクラスのすべてのテストケースで再利用できます。 -framework-reference/html/testing.html

ただし、JUnitテストクラスの束に対して、Springアプリケーションコンテキストを1回だけロードする方法があるのか​​どうか疑問に思っていました。

FWIW、Spring 3.0.5、JUnit 4.5を使用し、Mavenを使用してプロジェクトをビルドします。

73
Ramesh

はい、これは完全に可能です。テストクラスで同じlocations属性を使用するだけです。

@ContextConfiguration(locations = "classpath:test-context.xml")

Springはlocations属性によってアプリケーションコンテキストをキャッシュするため、同じlocationsが2回目に現れる場合、Springは新しいコンテキストを作成するのではなく、同じコンテキストを使用します。

この機能に関する記事を書きました: Spring統合テストの高速化 。また、Springドキュメントで詳細に説明されています: 9.3.2.1コンテキスト管理とキャッシュ

これには興味深い意味があります。 SpringはJUnitがいつ終了するかを知らないため、すべてのコンテキストforeverをキャッシュし、JVMシャットダウンフックを使用してそれらを閉じます。この動作(特に、異なるlocationsを持つテストクラスが多数ある場合)は、過剰なメモリ使用、メモリリークなどにつながる可能性があります。コンテキストをキャッシュする別の利点。

83

Tomasz Nurkiewicz's answer に追加するには、Spring 3.2.2以降@ContextHierarchy注釈を使用して、個別の関連付けられた複数のコンテキスト構造を持つことができます。これは、複数のテストクラスが(たとえば)インメモリデータベースセットアップ(datasource、EntityManagerFactory、tx managerなど)を共有する場合に役立ちます。

例えば:

@ContextHierarchy({
  @ContextConfiguration("/test-db-setup-context.xml"),
  @ContextConfiguration("FirstTest-context.xml")
})
@RunWith(SpringJUnit4ClassRunner.class)
public class FirstTest {
 ...
}

@ContextHierarchy({
  @ContextConfiguration("/test-db-setup-context.xml"),
  @ContextConfiguration("SecondTest-context.xml")
})
@RunWith(SpringJUnit4ClassRunner.class)
public class SecondTest {
 ...
}

この設定により、「test-db-setup-context.xml」を使用するコンテキストは1回だけ作成されますが、内部のBeanは個々の単体テストのコンテキストに注入できます

マニュアルの詳細: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/testing.html#testcontext-ctx-management (「- コンテキスト階層 ")

25
gerrytan