你可以使用大多数与测试相关的注解作为 元注解 来创建自定义的组合注解,并减少整个测试套件的配置重复。
你可以结合 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")
@Transactional
public class OrderRepositoryTests { }
@RunWith(SpringRunner.class)
@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})
@ActiveProfiles("dev")
@Transactional
public class UserRepositoryTests { }
如果我们发现我们在整个基于 JUnit 4 的测试套件中重复前面的配置,我们可以通过引入一个自定义的组合注解来减少重复,该注解集中了 Spring 的通用测试配置,如下所示:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})
@ActiveProfiles("dev")
@Transactional
public @interface TransactionalDevTestConfig { }
然后我们可以使用我们自定义的 @TransactionalDevTestConfig
注解来简化基于 JUnit 4 的各个测试类的配置,如下所示:
@RunWith(SpringRunner.class)
@TransactionalDevTestConfig
public class OrderRepositoryTests { }
@RunWith(SpringRunner.class)
@TransactionalDevTestConfig
public class UserRepositoryTests { }
如果我们编写使用 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 { }
如果我们发现我们在基于 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 { }
然后我们可以使用我们自定义的 @TransactionalDevTestConfig
注解来简化基于 JUnit Jupiter 的各个测试类的配置,如下所示:
@TransactionalDevTestConfig
class OrderRepositoryTests { }
@TransactionalDevTestConfig
class 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.Test
public @interface TransactionalIntegrationTest { }
然后我们可以使用我们自定义的 @TransactionalIntegrationTest
注解来简化基于 JUnit Jupiter 的各个测试方法的配置,如下所示:
@TransactionalIntegrationTest
void saveOrder() { }
@TransactionalIntegrationTest
void deleteOrder() { }
更多细节,请参见 Spring 注解编程模型维基页面。