你可以使用大多数与测试相关的注解作为 元注解 来创建自定义的组合注解,并减少整个测试套件的配置重复。
你可以结合 TestContext 框架使用以下每个元注解:
- @BootstrapWith
- @ContextConfiguration
- @ContextHierarchy
- @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")@Transactionalpublic class OrderRepositoryTests { }@RunWith(SpringRunner.class)@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})@ActiveProfiles("dev")@Transactionalpublic class UserRepositoryTests { }
如果我们发现我们在整个基于 JUnit 4 的测试套件中重复前面的配置,我们可以通过引入一个自定义的组合注解来减少重复,该注解集中了 Spring 的通用测试配置,如下所示:
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})@ActiveProfiles("dev")@Transactionalpublic @interface TransactionalDevTestConfig { }
然后我们可以使用我们自定义的 @TransactionalDevTestConfig注解来简化基于 JUnit 4 的各个测试类的配置,如下所示:
@RunWith(SpringRunner.class)@TransactionalDevTestConfigpublic class OrderRepositoryTests { }@RunWith(SpringRunner.class)@TransactionalDevTestConfigpublic class UserRepositoryTests { }
如果我们编写使用 JUnit Jupiter 的测试,我们可以进一步减少代码重复,因为 JUnit 5 中的注解也可以作为元注解使用。考虑一下下面的例子:
@ExtendWith(SpringExtension.class)@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})@ActiveProfiles("dev")@Transactionalclass OrderRepositoryTests { }@ExtendWith(SpringExtension.class)@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})@ActiveProfiles("dev")@Transactionalclass UserRepositoryTests { }
如果我们发现我们在基于 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")@Transactionalpublic @interface TransactionalDevTestConfig { }
然后我们可以使用我们自定义的 @TransactionalDevTestConfig注解来简化基于 JUnit Jupiter 的各个测试类的配置,如下所示:
@TransactionalDevTestConfigclass OrderRepositoryTests { }@TransactionalDevTestConfigclass UserRepositoryTests { }
由于 JUnit Jupiter 支持使用 @Test、@RepeatedTest、ParameterizedTest等作为元注解,你也可以在测试方法级别创建自定义的组成注解。例如,如果我们希望创建一个组合注解,将 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.Testpublic @interface TransactionalIntegrationTest { }
然后我们可以使用我们自定义的 @TransactionalIntegrationTest注解来简化基于 JUnit Jupiter 的各个测试方法的配置,如下所示:
@TransactionalIntegrationTestvoid saveOrder() { }@TransactionalIntegrationTestvoid deleteOrder() { }
更多细节,请参见 Spring 注解编程模型维基页面。
