La mayoría de las anotaciones relacionadas con las pruebas se pueden utilizar como metaanotaciones para crear sus propias anotaciones y reduzca la duplicación de configuración en el conjunto de pruebas.

Cada una de las siguientes anotaciones se puede utilizar como metaanotación en combinación con el marco TestContext.

  • @BootstrapWith

  • @ContextConfiguration

  • @ContextHierarchy

  • @ActiveProfiles

  • @TestPropertySource

  • @DirtiesContext

  • @WebAppConfiguration

  • @TestExecutionListeners

  • @Transaccional

  • @BeforeTransaction

  • @AfterTransaction

  • @Commit

  • @Rollback

  • @Sql

  • @SqlConfig

  • @SqlMergeMode

  • @SqlGroup

  • @Repeat (solo compatible con JUnit 4)

  • @Timed (solo compatible con JUnit 4)

  • @IfProfileValue (solo compatible con JUnit 4)

  • @ProfileValueSourceConfiguration (solo compatible con JUnit 4)

  • @SpringJUnitConfig (solo compatible con JUnit Jupiter)

  • @SpringJUnitWebConfig (solo compatible con JUnit Jupiter)

  • @TestConstructor (solo compatible con JUnit Jupiter)

  • @NestedTestConfiguration (solo compatible con JUnit Jupiter)

  • @EnabledIf (solo compatible con JUnit Jupiter)

  • @DisabledIf (solo compatible con JUnit Jupiter)

Considere el siguiente ejemplo:

Java
@RunWith(SpringRunner.class)
@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})
@ActiveProfiles("desarrollador")
@Transaccional
clase pública OrderRepositoryTests { }
@RunWith(SpringRunner.clase)
@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})
@ActiveProfiles("desarrollador")
@Transaccional
clase pública UserRepositoryTests { }
Kotlin
@RunWith(SpringRunner::clase)
@ContextConfiguration("/app-config.xml", "/test-data-access-config.xml")
@ActiveProfiles("desarrollador")
@Transaccional
clase OrderRepositoryTests { }
@RunWith(SpringRunner::clase)
@ContextConfiguration("/app-config.xml", "/test-data-access-config.xml")
@ActiveProfiles("desarrollador")
@Transaccional
clase UserRepositoryTests { }

Si encontramos que la configuración anterior se repite en nuestro conjunto de pruebas basado en JUnit 4, podemos reducir la duplicación introduciendo una anotación compuesta especial que centralice la configuración de prueba general para Spring, de la siguiente manera:

Java
@Target(ElementType.TYPE)
@Retención(RetentionPolicy.RUNTIME)
@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})
@ActiveProfiles("desarrollador")
@Transaccional
pública @interface TransactionalDevTestConfig { }
Kotlin
@Target(AnnotationTarget.TYPE)
@Retención(AnnotationRetention.RUNTIME)
@ContextConfiguration("/app-config.xml", "/test-data-access-config.xml")
@ActiveProfiles("desarrollador")
@Transaccional
clase de anotación TransactionalDevTestConfig { }

Luego puede utilizar nuestra anotación personalizada @TransactionalDevTestConfig para simplificar la configuración de clases de prueba individuales basadas en JUnit 4, como se muestra a continuación:

Java
@RunWith(SpringRunner.class)
@TransactionalDevTestConfig
clase pública OrderRepositoryTests { }
@RunWith(SpringRunner.clase)
@TransactionalDevTestConfig
clase pública UserRepositoryTests { }
Kotlin
@RunWith(SpringRunner::clase)
@TransactionalDevTestConfig
clase OrderRepositoryTests
@RunWith(SpringRunner::clase)
@TransactionalDevTestConfig
clase UserRepositoryTests

Si escribimos pruebas usando JUnit Jupiter, entonces podemos reducir aún más la duplicación de código porque las anotaciones en JUnit 5 también se pueden usar como metanotaciones. Considere el siguiente ejemplo:

Java
@ExtendWith(SpringExtension.class)
@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})
@ActiveProfiles("desarrollador")
@Transaccional
clase OrderRepositoryTests { }
@ExtendWith(SpringExtension.clase)
@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})
@ActiveProfiles("desarrollador")
@Transaccional
clase UserRepositoryTests { }
Kotlin
@ExtendWith(SpringExtension::class)
@ContextConfiguration("/app-config.xml", "/test-data-access-config.xml")
@ActiveProfiles("desarrollador")
@Transaccional
clase OrderRepositoryTests { }
@ExtendWith(SpringExtension::clase)
@ContextConfiguration("/app-config.xml", "/test-data-access-config.xml")
@ActiveProfiles("desarrollador")
@Transaccional
clase UserRepositoryTests { }

Si encontramos que la configuración anterior se repite en nuestro conjunto de pruebas basado en JUnit Jupiter, podemos reducir la duplicación introduciendo una anotación compuesta especial que centralice la configuración de prueba común para Spring y JUnit Jupiter, de la siguiente manera:

Java
@Target(ElementType.TYPE)
@Retención(RetentionPolicy.RUNTIME)
@ExtendWith(SpringExtension.clase)
@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})
@ActiveProfiles("desarrollador")
@Transaccional
pública @interface TransactionalDevTestConfig { }
Kotlin
@Target(AnnotationTarget.TYPE)
@Retención(AnnotationRetention.RUNTIME)
@ExtendWith(SpringExtension::clase)
@ContextConfiguration("/app-config.xml", "/test-data-access-config.xml")
@ActiveProfiles("desarrollador")
@Transaccional
clase de anotación TransactionalDevTestConfig { }

Luego puede utilizar nuestra anotación personalizada @TransactionalDevTestConfig para simplificar la configuración de clases de prueba individuales basadas en JUnit Jupite, como se muestra a continuación:

Java
@TransactionalDevTestConfig
clase OrderRepositoryTests { }
@TransactionalDevTestConfig
clase UserRepositoryTests { }
Kotlin
@TransactionalDevTestConfig
clase OrderRepositoryTests { }
@TransactionalDevTestConfig
clase UserRepositoryTests { }

Debido a que JUnit Jupiter admite el uso de @Test, @RepeatedTest, ParameterizedTest y otras como metaanotaciones, también puedes crear tus propias anotaciones compuestas. a nivel del método de prueba. Por ejemplo, si desea crear una anotación compuesta que combine las anotaciones @Test y @Tag de JUnit Jupiter con la anotación @Transactional de Spring, puedes crear una anotación @TransactionalIntegrationTest de la siguiente manera:

Java
@Target(ElementType.METHOD)
@Retención(RetentionPolicy.RUNTIME)
@Transaccional
@Tag("prueba de integración") // org.junit.jupiter.api.Tag
@Test // org.junit.jupiter.api.Test
public @interface Prueba de integración transaccional { }
Kotlin
@Target(AnnotationTarget.TYPE)
@Retención(AnnotationRetention.RUNTIME)
@Transaccional
@Tag("prueba de integración") // org.junit.jupiter.api.Tag
@Test // org.junit.jupiter.api.Test
clase de anotación TransactionalIntegrationTest { }

Luego puede utilizar nuestra anotación personalizada @TransactionalIntegrationTest para simplificar la configuración de métodos de prueba individuales basados en JUnit Jupiter de la siguiente manera:

Java
@TransactionalIntegrationTest
anular saveOrder() { }
@TransactionalIntegrationTest
anular eliminarOrden() { }
Kotlin
@TransactionalIntegrationTest
divertido saveOrder() { }
@TransactionalIntegrationTest
divertido eliminarOrden() { }

Puede encontrar más información en la página wiki Spring Modelo de programación de anotaciones.