測試的元註解支援

您可以使用大多數測試相關的註解作為元註解來建立自定義組合註解,從而減少整個測試套件中的配置重複。

您可以將以下每個註解作為元註解與TestContext framework結合使用。

  • @BootstrapWith

  • @ContextConfiguration

  • @ContextHierarchy

  • @ContextCustomizerFactories

  • @ActiveProfiles

  • @TestPropertySource

  • @DirtiesContext

  • @WebAppConfiguration

  • @TestExecutionListeners

  • @Transactional

  • @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 UserRepositoryTests

如果我們編寫使用 JUnit 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@RepeatedTestParameterizedTest 等用作元註解,因此您也可以在測試方法級別建立自定義組合註解。例如,如果我們希望建立一個組合註解,將 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 Annotation Programming Model維基頁面。