Meta-Annotation Support for Testing
您可以将大多数与测试相关的注释用作 meta-annotations 来创建自定义组合注释并减少整个测试套件的配置重复。
You can use most test-related annotations as meta-annotations to create custom composed annotations and reduce configuration duplication across a test suite.
您可以在与 TestContext framework 结合使用时使用以下每一个注解作为元注解。
You can use each of the following as a meta-annotation in conjunction with the TestContext framework.
-
@BootstrapWith
-
@ContextConfiguration
-
@ContextHierarchy
-
@ContextCustomizerFactories
-
@ActiveProfiles
-
@TestPropertySource
-
@DirtiesContext
-
@WebAppConfiguration
-
@TestExecutionListeners
-
@Transactional
-
@BeforeTransaction
-
@AfterTransaction
-
@Commit
-
@Rollback
-
@Sql
-
@SqlConfig
-
@SqlMergeMode
-
@SqlGroup
-
@Repeat
(only supported on JUnit 4) -
@Timed
(only supported on JUnit 4) -
@IfProfileValue
(only supported on JUnit 4) -
@ProfileValueSourceConfiguration
(only supported on JUnit 4) -
@SpringJUnitConfig
(only supported on JUnit Jupiter) -
@SpringJUnitWebConfig
(only supported on JUnit Jupiter) -
@TestConstructor
(only supported on JUnit Jupiter) -
@NestedTestConfiguration
(only supported on JUnit Jupiter) -
@EnabledIf
(only supported on JUnit Jupiter) -
@DisabledIf
(only supported on JUnit Jupiter)
请考虑以下示例:
Consider the following example:
-
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 的常见测试配置,如下所示:
If we discover that we are repeating the preceding configuration across our JUnit 4-based test suite, we can reduce the duplication by introducing a custom composed annotation that centralizes the common test configuration for Spring, as follows:
-
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 的各个测试类的配置,如下所示:
Then we can use our custom @TransactionalDevTestConfig
annotation to simplify the
configuration of individual JUnit 4 based test classes, as follows:
-
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 中的注解也可以用作元注解。考虑以下示例:
If we write tests that use JUnit Jupiter, we can reduce code duplication even further, since annotations in JUnit 5 can also be used as meta-annotations. Consider the following example:
-
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 的常见测试配置,如下所示:
If we discover that we are repeating the preceding configuration across our JUnit Jupiter-based test suite, we can reduce the duplication by introducing a custom composed annotation that centralizes the common test configuration for Spring and JUnit Jupiter, as follows:
-
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 的各个测试类的配置,如下所示:
Then we can use our custom @TransactionalDevTestConfig
annotation to simplify the
configuration of individual JUnit Jupiter based test classes, as follows:
-
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
注解,如下所示:
Since JUnit Jupiter supports the use of @Test
, @RepeatedTest
, ParameterizedTest
,
and others as meta-annotations, you can also create custom composed annotations at the
test method level. For example, if we wish to create a composed annotation that combines
the @Test
and @Tag
annotations from JUnit Jupiter with the @Transactional
annotation from Spring, we could create an @TransactionalIntegrationTest
annotation, as
follows:
-
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 的各个测试方法的配置,如下所示:
Then we can use our custom @TransactionalIntegrationTest
annotation to simplify the
configuration of individual JUnit Jupiter based test methods, as follows:
-
Java
-
Kotlin
@TransactionalIntegrationTest
void saveOrder() { }
@TransactionalIntegrationTest
void deleteOrder() { }
@TransactionalIntegrationTest
fun saveOrder() { }
@TransactionalIntegrationTest
fun deleteOrder() { }
有关更多详细信息,请参阅 Spring 注释编程模型wiki 页面。
For further details, see the Spring Annotation Programming Model wiki page.