テスト用のメタアノテーションのサポート
ほとんどのテスト関連のアノテーションをメタアノテーションとして使用して、カスタム合成アノテーションを作成し、テストスイート全体での構成の重複を減らすことができます。
次のそれぞれを TestContext フレームワークと組み合わせてメタアノテーションとして使用できます。
@BootstrapWith@ContextConfiguration@ContextHierarchy@ContextCustomizerFactories@ActiveProfiles@TestPropertySource@DirtiesContext@WebAppConfiguration@TestExecutionListeners@BeforeTransaction@AfterTransaction@Commit@Rollback@Sql@SqlConfig@SqlMergeMode@SqlGroup@Repeat(JUnit 4 でのみサポート)@Timed(JUnit 4 でのみサポート)@IfProfileValue(JUnit 4 でのみサポート)@ProfileValueSourceConfiguration(JUnit 4 でのみサポート)@SpringJUnitConfig(JUnit Jupiter でのみサポート)@SpringJUnitWebConfig(JUnit Jupiter でのみサポート)@TestConstructor(JUnit Jupiter でのみサポート)@NestedTestConfiguration(JUnit Jupiter でのみサポート)@EnabledIf(JUnit Jupiter でのみサポート)@DisabledIf(JUnit Jupiter でのみサポート)
次の例を考えてみましょう。
Java
Kotlin
@RunWith(SpringRunner.class)
@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})
@ActiveProfiles("dev")
@Transactional
public class OrderRepositoryTests { }
@RunWith(SpringRunner.class)
@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})
@ActiveProfiles("dev")
@Transactional
public class UserRepositoryTests { }@RunWith(SpringRunner::class)
@ContextConfiguration("/app-config.xml", "/test-data-access-config.xml")
@ActiveProfiles("dev")
@Transactional
class OrderRepositoryTests { }
@RunWith(SpringRunner::class)
@ContextConfiguration("/app-config.xml", "/test-data-access-config.xml")
@ActiveProfiles("dev")
@Transactional
class UserRepositoryTests { }JUnit 4 ベースのテストスイート全体で上記の構成を繰り返していることがわかった場合は、次のように、Spring の共通のテスト構成を集中化するカスタム合成アノテーションを導入することで、重複を減らすことができます。
Java
Kotlin
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})
@ActiveProfiles("dev")
@Transactional
public @interface TransactionalDevTestConfig { }@Target(AnnotationTarget.TYPE)
@Retention(AnnotationRetention.RUNTIME)
@ContextConfiguration("/app-config.xml", "/test-data-access-config.xml")
@ActiveProfiles("dev")
@Transactional
annotation class TransactionalDevTestConfig { } 次に、次のように、カスタム @TransactionalDevTestConfig アノテーションを使用して、個々の JUnit 4 ベースのテストクラスの構成を簡素化できます。
Java
Kotlin
@RunWith(SpringRunner.class)
@TransactionalDevTestConfig
public class OrderRepositoryTests { }
@RunWith(SpringRunner.class)
@TransactionalDevTestConfig
public class UserRepositoryTests { }@RunWith(SpringRunner::class)
@TransactionalDevTestConfig
class OrderRepositoryTests
@RunWith(SpringRunner::class)
@TransactionalDevTestConfig
class UserRepositoryTestsJUnit Jupiter を使用するテストを記述する場合、JUnit 5 のアノテーションもメタアノテーションとして使用できるため、コードの重複をさらに減らすことができます。次の例を考えてみましょう。
Java
Kotlin
@ExtendWith(SpringExtension.class)
@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})
@ActiveProfiles("dev")
@Transactional
class OrderRepositoryTests { }
@ExtendWith(SpringExtension.class)
@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})
@ActiveProfiles("dev")
@Transactional
class UserRepositoryTests { }@ExtendWith(SpringExtension::class)
@ContextConfiguration("/app-config.xml", "/test-data-access-config.xml")
@ActiveProfiles("dev")
@Transactional
class OrderRepositoryTests { }
@ExtendWith(SpringExtension::class)
@ContextConfiguration("/app-config.xml", "/test-data-access-config.xml")
@ActiveProfiles("dev")
@Transactional
class UserRepositoryTests { }JUnit Jupiter ベースのテストスイート全体で上記の構成を繰り返していることがわかった場合、次のように、Spring と JUnit Jupiter の共通のテスト構成を集中化するカスタム構成アノテーションを導入することで、重複を減らすことができます。
Java
Kotlin
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@ExtendWith(SpringExtension.class)
@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})
@ActiveProfiles("dev")
@Transactional
public @interface TransactionalDevTestConfig { }@Target(AnnotationTarget.TYPE)
@Retention(AnnotationRetention.RUNTIME)
@ExtendWith(SpringExtension::class)
@ContextConfiguration("/app-config.xml", "/test-data-access-config.xml")
@ActiveProfiles("dev")
@Transactional
annotation class TransactionalDevTestConfig { } 次に、次のように、カスタム @TransactionalDevTestConfig アノテーションを使用して、個々の JUnit Jupiter ベースのテストクラスの構成を簡素化できます。
Java
Kotlin
@TransactionalDevTestConfig
class OrderRepositoryTests { }
@TransactionalDevTestConfig
class UserRepositoryTests { }@TransactionalDevTestConfig
class OrderRepositoryTests { }
@TransactionalDevTestConfig
class UserRepositoryTests { }JUnit Jupiter は @Test、@RepeatedTest、ParameterizedTest などのメタアノテーションとしての使用をサポートしているため、テストメソッドレベルでカスタム合成アノテーションを作成することもできます。例: JUnit Jupiter の @Test アノテーションと @Tag アノテーションを Spring の @Transactional アノテーションと組み合わせる合成アノテーションを作成する場合、次のように @TransactionalIntegrationTest アノテーションを作成できます。
Java
Kotlin
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Transactional
@Tag("integration-test") // org.junit.jupiter.api.Tag
@Test // org.junit.jupiter.api.Test
public @interface TransactionalIntegrationTest { }@Target(AnnotationTarget.TYPE)
@Retention(AnnotationRetention.RUNTIME)
@Transactional
@Tag("integration-test") // org.junit.jupiter.api.Tag
@Test // org.junit.jupiter.api.Test
annotation class TransactionalIntegrationTest { } 次に、カスタム @TransactionalIntegrationTest アノテーションを使用して、次のように、個々の JUnit Jupiter ベースのテストメソッドの構成を簡素化できます。
Java
Kotlin
@TransactionalIntegrationTest
void saveOrder() { }
@TransactionalIntegrationTest
void deleteOrder() { }@TransactionalIntegrationTest
fun saveOrder() { }
@TransactionalIntegrationTest
fun deleteOrder() { }詳細については、Spring アノテーションプログラミングモデル [GitHub] (英語) wiki ページを参照してください。