Интеграционное тестирование в Spring: поддержка метааннотаций для тестирования

Вы можете использовать большинство аннотаций, связанных с тестами, в качестве метааннотаций для создания настраиваемых составных аннотаций и уменьшения дублирования конфигурации в наборе тестов.

Вы можете использовать каждую из следующих метааннотаций в сочетании с TestContext framework.

  • @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)
  • @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 и других в качестве метааннотаций, вы также можете создавать собственные составные аннотации на уровне метода тестирования. Например, если мы хотим создать составную аннотацию, которая объединяет аннотации @Test и @Tag из JUnit Jupiter с аннотацией @Transactional из Spring, мы могли бы создать аннотацию @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() { }


Читайте также:


Комментарии

Популярные сообщения из этого блога

Методы класса Object в Java

Как получить текущий timestamp в Java

Основные опции JVM для повышения производительности и отладки