跳到主要内容

测试的元注解支持

DeepSeek V3 中英对照 Meta-Annotation Support for Testing

你可以将大多数与测试相关的注解用作元注解来创建自定义的组合注解,从而减少测试套件中的配置重复。

你可以将以下每一项作为元注解与 TestContext 框架 结合使用。

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

考虑以下示例:

@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 { }
java

如果发现我们在基于 JUnit 4 的测试套件中重复了前面的配置,我们可以通过引入一个自定义的组合注解来减少重复,该注解将 Spring 的通用测试配置集中起来,如下所示:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})
@ActiveProfiles("dev")
@Transactional
public @interface TransactionalDevTestConfig { }
java

然后我们可以使用自定义的 @TransactionalDevTestConfig 注解来简化基于 JUnit 4 的单个测试类的配置,如下所示:

@RunWith(SpringRunner.class)
@TransactionalDevTestConfig
public class OrderRepositoryTests { }

@RunWith(SpringRunner.class)
@TransactionalDevTestConfig
public class UserRepositoryTests { }
java

如果我们编写使用 JUnit Jupiter 的测试,我们可以进一步减少代码重复,因为 JUnit 5 中的注解也可以用作元注解。考虑以下示例:

@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 { }
java

如果发现我们在基于 JUnit Jupiter 的测试套件中重复了前面的配置,我们可以通过引入一个自定义的组合注解来减少重复,该注解将 Spring 和 JUnit Jupiter 的通用测试配置集中起来,如下所示:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@ExtendWith(SpringExtension.class)
@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})
@ActiveProfiles("dev")
@Transactional
public @interface TransactionalDevTestConfig { }
java

然后我们可以使用自定义的 @TransactionalDevTestConfig 注解来简化基于 JUnit Jupiter 的单个测试类的配置,如下所示:

@TransactionalDevTestConfig
class OrderRepositoryTests { }

@TransactionalDevTestConfig
class UserRepositoryTests { }
java

由于 JUnit Jupiter 支持将 @Test@RepeatedTestParameterizedTest 等作为元注解使用,因此你也可以在测试方法级别创建自定义的组合注解。例如,如果我们希望创建一个组合注解,将 JUnit Jupiter 中的 @Test@Tag 注解与 Spring 中的 @Transactional 注解结合起来,我们可以创建一个 @TransactionalIntegrationTest 注解,如下所示:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Transactional
@Tag("integration-test") // org.junit.jupiter.api.Tag
@Test // org.junit.jupiter.api.Test
public @interface TransactionalIntegrationTest { }
java

然后我们可以使用自定义的 @TransactionalIntegrationTest 注解来简化基于 JUnit Jupiter 的单个测试方法的配置,如下所示:

@TransactionalIntegrationTest
void saveOrder() { }

@TransactionalIntegrationTest
void deleteOrder() { }
java

有关更多详细信息,请参阅 Spring 注解编程模型 维基页面。