このバージョンはまだ開発中であり、まだ安定しているとは見なされていません。最新の安定バージョンについては、Spring Framework 6.2.8 を使用してください!

TestContext フレームワークサポートクラス

このセクションでは、JUnit および TestNG で Spring、TestContext、フレームワークをサポートするさまざまなクラスについて説明します。

JUnit Jupiter 用 SpringExtension

The Spring TestContext Framework offers full integration with the JUnit Jupiter testing framework, originally introduced in JUnit 5. By annotating test classes with @ExtendWith(SpringExtension.class), you can implement standard JUnit Jupiter-based unit and integration tests and simultaneously reap the benefits of the TestContext framework, such as support for loading application contexts, dependency injection of test instances, transactional test method execution, and so on.

さらに、JUnit Jupiter の豊富な拡張 API のおかげで、Spring は、Spring が JUnit 4 および TestNG に対してサポートする機能セットに加えて、以下の機能を提供します。

次のコードリストは、SpringExtension を @ContextConfiguration と組み合わせて使用するようにテストクラスを構成する方法を示しています。

  • Java

  • Kotlin

// Instructs JUnit Jupiter to extend the test with Spring support.
@ExtendWith(SpringExtension.class)
// Instructs Spring to load an ApplicationContext from TestConfig.class
@ContextConfiguration(classes = TestConfig.class)
class SimpleTests {

	@Test
	void testMethod() {
		// test logic...
	}
}
// Instructs JUnit Jupiter to extend the test with Spring support.
@ExtendWith(SpringExtension::class)
// Instructs Spring to load an ApplicationContext from TestConfig::class
@ContextConfiguration(classes = [TestConfig::class])
class SimpleTests {

	@Test
	fun testMethod() {
		// test logic...
	}
}

Since you can also use annotations in JUnit Jupiter as meta-annotations, Spring provides the @SpringJUnitConfig and @SpringJUnitWebConfig composed annotations to simplify the configuration of the test ApplicationContext and JUnit Jupiter.

次の例では、@SpringJUnitConfig を使用して、前の例で使用した構成の量を削減します。

  • Java

  • Kotlin

// Instructs Spring to register the SpringExtension with JUnit
// Jupiter and load an ApplicationContext from TestConfig.class
@SpringJUnitConfig(TestConfig.class)
class SimpleTests {

	@Test
	void testMethod() {
		// test logic...
	}
}
// Instructs Spring to register the SpringExtension with JUnit
// Jupiter and load an ApplicationContext from TestConfig.class
@SpringJUnitConfig(TestConfig::class)
class SimpleTests {

	@Test
	fun testMethod() {
		// test logic...
	}
}

同様に、次の例では、@SpringJUnitWebConfig を使用して、JUnit Jupiter で使用する WebApplicationContext を作成します。

  • Java

  • Kotlin

// Instructs Spring to register the SpringExtension with JUnit
// Jupiter and load a WebApplicationContext from TestWebConfig.class
@SpringJUnitWebConfig(TestWebConfig.class)
class SimpleWebTests {

	@Test
	void testMethod() {
		// test logic...
	}
}
// Instructs Spring to register the SpringExtension with JUnit
// Jupiter and load a WebApplicationContext from TestWebConfig::class
@SpringJUnitWebConfig(TestWebConfig::class)
class SimpleWebTests {

	@Test
	fun testMethod() {
		// test logic...
	}
}

詳細については、Spring JUnit Jupiter テストアノテーションの @SpringJUnitConfig および @SpringJUnitWebConfig の資料を参照してください。

SpringExtension による依存関係の注入

SpringExtension は、JUnit Jupiter の ParameterResolver (英語) 拡張 API を実装します。これにより、Spring は、テストコンストラクター、テストメソッド、テストライフサイクルコールバックメソッドに依存関係の注入を提供できます。

具体的には、SpringExtension は、テストの ApplicationContext からの依存関係を、Spring の @BeforeTransaction および @AfterTransaction または JUnit の @BeforeAll@AfterAll@BeforeEach@AfterEach@Test@RepeatedTest@ParameterizedTest などでアノテーションが付けられたテストコンストラクターおよびメソッドに注入できます。

コンストラクターインジェクション

JUnit Jupiter テストクラスのコンストラクター内の特定のパラメーターが型 ApplicationContext (またはそのサブ型)であるか、@Autowired@Qualifier@Value でアノテーションが付けられているかメタアノテーションが付けられている場合、Spring はその特定のパラメーターの値に対応する Bean またはテストの ApplicationContext からの値。

Spring は、コンストラクターが autowirable であると見なされる場合、テストクラスコンストラクターのすべての引数をオートワイヤーするように構成することもできます。コンストラクターは、次の条件のいずれかが(優先順位の順に)満たされる場合、自動書き込み可能と見なされます。

  • コンストラクターには @Autowired のアノテーションが付けられます。

  • @TestConstructor は、autowireMode 属性が ALL に設定されたテストクラスに存在またはメタ存在します。

  • デフォルトのテストコンストラクターのオートワイヤーモードは ALL に変更されました。

@TestConstructor の使用と、グローバルテストコンストラクターのオートワイヤーモードを変更する方法の詳細については、@TestConstructor を参照してください

テストクラスのコンストラクターが autowirable であると見なされる場合、Spring はコンストラクター内のすべてのパラメーターの引数を解決する責任を負います。その結果、JUnit Jupiter に登録されている他の ParameterResolver は、そのようなコンストラクターのパラメーターを解決できません。

@DirtiesContext を使用してテストメソッドの前または後にテストの ApplicationContext を閉じる場合、テストクラスのコンストラクターインジェクションを JUnit Jupiter の @TestInstance(PER_CLASS) サポートと組み合わせて使用しないでください。

その理由は、@TestInstance(PER_CLASS) が JUnit Jupiter にテストメソッドの呼び出しの間にテストインスタンスをキャッシュするように指示するためです。その結果、テストインスタンスは、その後閉じられた ApplicationContext から最初に注入された Bean への参照を保持します。このようなシナリオではテストクラスのコンストラクターが 1 回だけ呼び出されるため、依存関係の注入は再度行われず、後続のテストは閉じられた ApplicationContext の Bean と対話し、エラーが発生する可能性があります。

@TestInstance(PER_CLASS) と組み合わせて @DirtiesContext を「テストメソッド前」または「テストメソッド後」モードで使用するには、Spring からの依存関係をフィールドまたは setter インジェクションを介して提供し、テストメソッド呼び出しの間に再インジェクトできるように構成する必要があります。

次の例では、Spring は、TestConfig.class から OrderServiceIntegrationTests コンストラクターにロードされた ApplicationContext から OrderService Bean を注入します。

  • Java

  • Kotlin

@SpringJUnitConfig(TestConfig.class)
class OrderServiceIntegrationTests {

	private final OrderService orderService;

	@Autowired
	OrderServiceIntegrationTests(OrderService orderService) {
		this.orderService = orderService;
	}

	// tests that use the injected OrderService
}
@SpringJUnitConfig(TestConfig::class)
class OrderServiceIntegrationTests @Autowired constructor(private val orderService: OrderService){
	// tests that use the injected OrderService
}

この機能により、テストの依存関係が final になり、不変になります。

spring.test.constructor.autowire.mode プロパティが all の場合(@TestConstructor を参照)、前の例のコンストラクターでの @Autowired の宣言を省略して、次のようにすることができます。

  • Java

  • Kotlin

@SpringJUnitConfig(TestConfig.class)
class OrderServiceIntegrationTests {

	private final OrderService orderService;

	OrderServiceIntegrationTests(OrderService orderService) {
		this.orderService = orderService;
	}

	// tests that use the injected OrderService
}
@SpringJUnitConfig(TestConfig::class)
class OrderServiceIntegrationTests(val orderService:OrderService) {
	// tests that use the injected OrderService
}

メソッドインジェクション

JUnit Jupiter テストメソッドまたはテストライフサイクルコールバックメソッドのパラメーターが型 ApplicationContext (またはそのサブ型)であるか、@Autowired@Qualifier@Value でアノテーションが付けられているかメタアノテーションが付けられている場合、Spring はその特定のパラメーターの値をテストの ApplicationContext からの対応する Bean。

次の例では、Spring は TestConfig.class から deleteOrder() テストメソッドにロードされた ApplicationContext から OrderService を挿入します。

  • Java

  • Kotlin

@SpringJUnitConfig(TestConfig.class)
class OrderServiceIntegrationTests {

	@Test
	void deleteOrder(@Autowired OrderService orderService) {
		// use orderService from the test's ApplicationContext
	}
}
@SpringJUnitConfig(TestConfig::class)
class OrderServiceIntegrationTests {

	@Test
	fun deleteOrder(@Autowired orderService: OrderService) {
		// use orderService from the test's ApplicationContext
	}
}

JUnit Jupiter の ParameterResolver サポートの堅牢性により、Spring だけでなく、JUnit Jupiter 自体または他のサードパーティの拡張機能からも、単一のメソッドに複数の依存関係を注入できます。

次の例は、Spring と JUnit Jupiter の両方で placeOrderRepeatedly() テストメソッドに依存関係を同時に注入するメソッドを示しています。

  • Java

  • Kotlin

@SpringJUnitConfig(TestConfig.class)
class OrderServiceIntegrationTests {

	@RepeatedTest(10)
	void placeOrderRepeatedly(RepetitionInfo repetitionInfo,
			@Autowired OrderService orderService) {

		// use orderService from the test's ApplicationContext
		// and repetitionInfo from JUnit Jupiter
	}
}
@SpringJUnitConfig(TestConfig::class)
class OrderServiceIntegrationTests {

	@RepeatedTest(10)
	fun placeOrderRepeatedly(repetitionInfo:RepetitionInfo, @Autowired orderService:OrderService) {

		// use orderService from the test's ApplicationContext
		// and repetitionInfo from JUnit Jupiter
	}
}

JUnit Jupiter の @RepeatedTest を使用すると、テストメソッドが RepetitionInfo にアクセスできることに注意してください。

@Nested テストクラスの構成

Spring TestContext フレームワークは、JUnit Jupiter の @Nested テストクラスでのテスト関連のアノテーションの使用をサポートしています。これには、包含クラスからテストクラス構成を継承するためのファーストクラスのサポートが含まれており、そのような構成はデフォルトで継承されます。デフォルトの INHERIT モードから OVERRIDE モードに変更するには、個々の @Nested テストクラスに @NestedTestConfiguration(EnclosingConfiguration.OVERRIDE) アノテーションを付けます。明示的な @NestedTestConfiguration 宣言は、アノテーションが付けられたテストクラスだけでなく、そのサブクラスとネストされたクラスにも適用されます。トップレベルのテストクラスに @NestedTestConfiguration アノテーションを付けると、それがネストされたすべてのテストクラスに再帰的に適用されます。

Spring、TestContext、フレームワークと統合され、包含クラス階層内でのアノテーション継承をサポートする必要があるコンポーネントを開発している場合は、@NestedTestConfiguration セマンティクスを尊重するために、TestContextAnnotationUtils で提供されるアノテーション検索ユーティリティを使用する必要があります。

開発チームがデフォルトを OVERRIDE に変更できるようにするために(たとえば、Spring Framework 5.0 から 5.2 との互換性のために)、デフォルトモードは、JVM システムプロパティまたはクラスパスのルートにある spring.properties ファイルを介してグローバルに変更できます。詳細については、「デフォルトの包含構成継承モードの変更」ノートを参照してください。

次の "Hello World" の例は非常に単純化されていますが、@Nested テストクラスによって継承される最上位クラスで共通の構成を宣言する方法を示しています。この特定の例では、TestConfig 構成クラスのみが継承されます。ネストされた各テストクラスは、独自のアクティブなプロファイルのセットを提供し、ネストされた各テストクラスに個別の ApplicationContext を提供します (詳細については、コンテキストキャッシングを参照してください)。サポートされているアノテーションのリストを参照して、@Nested テストクラスで継承できるアノテーションを確認してください。

  • Java

  • Kotlin

@SpringJUnitConfig(TestConfig.class)
class GreetingServiceTests {

	@Nested
	@ActiveProfiles("lang_en")
	class EnglishGreetings {

		@Test
		void hello(@Autowired GreetingService service) {
			assertThat(service.greetWorld()).isEqualTo("Hello World");
		}
	}

	@Nested
	@ActiveProfiles("lang_de")
	class GermanGreetings {

		@Test
		void hello(@Autowired GreetingService service) {
			assertThat(service.greetWorld()).isEqualTo("Hallo Welt");
		}
	}
}
@SpringJUnitConfig(TestConfig::class)
class GreetingServiceTests {

	@Nested
	@ActiveProfiles("lang_en")
	inner class EnglishGreetings {

		@Test
		fun hello(@Autowired service:GreetingService) {
			assertThat(service.greetWorld()).isEqualTo("Hello World")
		}
	}

	@Nested
	@ActiveProfiles("lang_de")
	inner class GermanGreetings {

		@Test
		fun hello(@Autowired service:GreetingService) {
			assertThat(service.greetWorld()).isEqualTo("Hallo Welt")
		}
	}
}

JUnit 4 サポート

Spring JUnit 4 ランナー

JUnit 4 is officially in maintenance mode, and JUnit 4 support in Spring is deprecated since Spring Framework 7.0 in favor of the SpringExtension and JUnit Jupiter.

Spring TestContext フレームワークは、カスタムランナー(JUnit 4.12 以上でサポート)を介して JUnit 4 と完全に統合されています。テストクラスに @RunWith(SpringJUnit4ClassRunner.class) または短い @RunWith(SpringRunner.class) バリアントをアノテーションすることにより、開発者は標準の JUnit 4 ベースのユニットおよび統合テストを実装し、同時にアプリケーションコンテキストのロードのサポート、テストインスタンスの依存性注入、トランザクションテストなど、TestContext フレームワークの利点を享受できます。メソッドの実行など。Spring TestContext フレームワークを代替ランナー(JUnit 4 の Parameterized ランナーなど)またはサードパーティランナー(MockitoJUnitRunner など)で使用する場合は、オプションで Spring の JUnit ルールのサポートを代わりに使用できます。

次のコードリストは、テストクラスをカスタム Spring Runner で実行するように構成するための最小要件を示しています。

  • Java

  • Kotlin

@RunWith(SpringRunner.class)
@TestExecutionListeners({})
public class SimpleTest {

	@Test
	public void testMethod() {
		// test logic...
	}
}
@RunWith(SpringRunner::class)
@TestExecutionListeners
class SimpleTest {

	@Test
	fun testMethod() {
		// test logic...
	}
}

上記の例では、@TestExecutionListeners が空のリストで構成され、デフォルトのリスナーを無効にします。そうしないと、ApplicationContext を @ContextConfiguration で構成する必要があります。

Spring JUnit 4 ルール

JUnit 4 is officially in maintenance mode, and JUnit 4 support in Spring is deprecated since Spring Framework 7.0 in favor of the SpringExtension and JUnit Jupiter.

org.springframework.test.context.junit4.rules パッケージは、次の JUnit 4 ルールを提供します(JUnit 4.12 以降でサポートされます)。

  • SpringClassRule

  • SpringMethodRule

SpringClassRule は Spring TestContext フレームワークのクラスレベルの機能をサポートする JUnit TestRule であり、SpringMethodRule は Spring TestContext フレームワークのインスタンスレベルおよびメソッドレベルの機能をサポートする JUnit MethodRule です。

SpringRunner とは対照的に、Spring のルールベースの JUnit サポートには、org.junit.runner.Runner の実装に依存しないという利点があるため、既存の代替ランナー(JUnit 4 の Parameterized など)またはサードパーティランナー(MockitoJUnitRunner など)と組み合わせることができます)。

TestContext フレームワークのすべての機能をサポートするには、SpringClassRule と SpringMethodRule を組み合わせる必要があります。次の例は、統合テストでこれらのルールを宣言する適切な方法を示しています。

  • Java

  • Kotlin

// Optionally specify a non-Spring Runner via @RunWith(...)
@ContextConfiguration
public class IntegrationTest {

	@ClassRule
	public static final SpringClassRule springClassRule = new SpringClassRule();

	@Rule
	public final SpringMethodRule springMethodRule = new SpringMethodRule();

	@Test
	public void testMethod() {
		// test logic...
	}
}
// Optionally specify a non-Spring Runner via @RunWith(...)
@ContextConfiguration
class IntegrationTest {

	@Rule
	val springMethodRule = SpringMethodRule()

	@Test
	fun testMethod() {
		// test logic...
	}

	companion object {
		@ClassRule
		val springClassRule = SpringClassRule()
	}
}

JUnit 4 基本クラス

JUnit 4 is officially in maintenance mode, and JUnit 4 support in Spring is deprecated since Spring Framework 7.0 in favor of the SpringExtension and JUnit Jupiter.

org.springframework.test.context.junit4 パッケージは、JUnit 4 ベースのテストケースに次のサポートクラスを提供します(JUnit 4.12 以上でサポートされます)。

  • AbstractJUnit4SpringContextTests

  • AbstractTransactionalJUnit4SpringContextTests

AbstractJUnit4SpringContextTests は、Spring TestContext フレームワークを JUnit4 環境での明示的な ApplicationContext テストサポートと統合する抽象基本テストクラスです。AbstractJUnit4SpringContextTests を継承すると、protected applicationContext インスタンス変数にアクセスできます。この変数を使用して、明示的な Bean ルックアップを実行したり、コンテキスト全体の状態をテストしたりできます。

AbstractTransactionalJUnit4SpringContextTests は、AbstractJUnit4SpringContextTests の抽象的なトランザクション拡張であり、JDBC アクセスにいくつかの便利な機能を追加します。このクラスは、javax.sql.DataSource Bean および PlatformTransactionManager Bean が ApplicationContext で定義されていることを想定しています。AbstractTransactionalJUnit4SpringContextTests を継承すると、SQL ステートメントを実行してデータベースを照会するために使用できる protected jdbcTemplate インスタンス変数にアクセスできます。このようなクエリを使用して、データベース関連のアプリケーションコードを実行する前後の両方でデータベースの状態を確認できます。Spring は、このようなクエリがアプリケーションコードと同じトランザクションのスコープで実行されることを保証します。ORM ツールと組み合わせて使用する場合は、検知を避けてください。JDBC テストのサポートで説明したように、AbstractTransactionalJUnit4SpringContextTests は、前述の jdbcTemplate を使用して JdbcTestUtils のメソッドに委譲する便利なメソッドも提供します。さらに、AbstractTransactionalJUnit4SpringContextTests は、構成された DataSource に対して SQL スクリプトを実行するための executeSqlScript(..) メソッドを提供します。

これらのクラスは拡張に便利です。テストクラスを Spring 固有のクラス階層に結び付けたくない場合は、@RunWith(SpringRunner.class) または Spring の JUnit ルールを使用して独自のカスタムテストクラスを構成できます。

TestNG サポート

org.springframework.test.context.testng パッケージは、TestNG ベースのテストケースに対して以下のサポートクラスを提供します。

  • AbstractTestNGSpringContextTests

  • AbstractTransactionalTestNGSpringContextTests

AbstractTestNGSpringContextTests は、Spring TestContext フレームワークを TestNG 環境での明示的な ApplicationContext テストサポートと統合する抽象基本テストクラスです。AbstractTestNGSpringContextTests を継承すると、protected applicationContext インスタンス変数にアクセスできます。この変数を使用して、明示的な Bean ルックアップを実行したり、コンテキスト全体の状態をテストしたりできます。

AbstractTransactionalTestNGSpringContextTests は、AbstractTestNGSpringContextTests の抽象的なトランザクション拡張であり、JDBC アクセスにいくつかの便利な機能を追加します。このクラスは、javax.sql.DataSource Bean および PlatformTransactionManager Bean が ApplicationContext で定義されていることを想定しています。AbstractTransactionalTestNGSpringContextTests を継承すると、SQL ステートメントを実行してデータベースを照会するために使用できる protected jdbcTemplate インスタンス変数にアクセスできます。このようなクエリを使用して、データベース関連のアプリケーションコードを実行する前後の両方でデータベースの状態を確認できます。Spring は、このようなクエリがアプリケーションコードと同じトランザクションのスコープで実行されることを保証します。ORM ツールと組み合わせて使用する場合は、検知を避けてください。JDBC テストのサポートで説明したように、AbstractTransactionalTestNGSpringContextTests は、前述の jdbcTemplate を使用して JdbcTestUtils のメソッドに委譲する便利なメソッドも提供します。さらに、AbstractTransactionalTestNGSpringContextTests は、構成された DataSource に対して SQL スクリプトを実行するための executeSqlScript(..) メソッドを提供します。

これらのクラスは拡張に便利です。テストクラスを Spring 固有のクラス階層に関連付けたくない場合は、@ContextConfiguration@TestExecutionListeners などを使用し、テストクラスを TestContextManager で手動でインストルメント化することにより、独自のカスタムテストクラスを構成できます。テストクラスをインストルメント化する方法の例については、AbstractTestNGSpringContextTests のソースコードを参照してください。