«1. Обзор

При тестировании приложения Spring, которое опирается на уровень персистентности, такой как JPA, мы можем захотеть настроить источник тестовых данных для использования меньшей и более быстрой базы данных — той, которая отличается от той, которую мы использовать для запуска приложения, чтобы сделать выполнение наших тестов намного проще.

Настройка источника данных в Spring требует определения bean-компонента типа DataSource либо вручную, либо, при использовании Spring Boot, через стандартные свойства приложения.

В этом кратком руководстве мы рассмотрим несколько способов настройки отдельного источника данных для тестирования в Spring.

2. Зависимости Maven

Мы собираемся создать приложение Spring Boot, используя Spring JPA и тестирование, поэтому нам понадобятся следующие зависимости:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency> 
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
</dependency>

Последние версии spring-boot-starter-data -jpa, h2 и spring-boot-starter-test можно загрузить с Maven Central.

Давайте рассмотрим несколько различных способов настройки DataSource для тестирования.

3. Использование стандартного файла свойств в Spring Boot

Стандартный файл свойств, автоматически загружаемый Spring Boot при запуске приложения, называется application.properties и находится в папке src/main/resources.

Если мы хотим использовать разные свойства для тестов, то мы можем переопределить файл свойств в основной папке, поместив другой файл с таким же именем в src/test/resources.

Файл application.properties в папке src/test/resources должен содержать стандартные пары ключ-значение, необходимые для настройки источника данных. Эти свойства имеют префикс spring.datasource.

Например, давайте настроим базу данных H2 в памяти в качестве источника данных для тестов:

spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
spring.datasource.username=sa
spring.datasource.password=sa

Spring Boot будет использовать эти свойства для автоматической настройки bean-компонента DataSource.

Давайте определим очень простой GenericEntity и репозиторий, используя Spring JPA:

@Entity
public class GenericEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String value;

    //standard constructors, getters, setters
}
public interface GenericEntityRepository
  extends JpaRepository<GenericEntity, Long> { }

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class SpringBootJPAIntegrationTest {
 
    @Autowired
    private GenericEntityRepository genericEntityRepository;

    @Test
    public void givenGenericEntityRepository_whenSaveAndRetreiveEntity_thenOK() {
        GenericEntity genericEntity = genericEntityRepository
          .save(new GenericEntity("test"));
        GenericEntity foundEntity = genericEntityRepository
          .findOne(genericEntity.getId());
 
        assertNotNull(foundEntity);
        assertEquals(genericEntity.getValue(), foundEntity.getValue());
    }
}

Далее, давайте напишем тест JUnit для репозитория. Чтобы тест в приложении Spring Boot мог использовать определенные нами стандартные свойства источника данных, он должен быть аннотирован с помощью @SpringBootTest:

4. Использование файла пользовательских свойств

Если мы не не хотите использовать стандартный файл application.properties и ключи, или, если мы не используем Spring Boot, мы можем определить собственный файл .properties с пользовательскими ключами, а затем прочитать этот файл в классе @Configuration для создания bean-компонента DataSource. на основе содержащихся в нем значений.

Этот файл будет помещен в папку src/main/resources для нормального режима работы приложения и в папку src/test/resources для того, чтобы тесты могли его подобрать.

jdbc.driverClassName=org.h2.Driver
jdbc.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
jdbc.username=sa
jdbc.password=sa

Давайте создадим файл с именем persistence-generic-entity.properties, который использует базу данных H2 в памяти для тестов, и поместим его в папку src/test/resources:

@Configuration
@EnableJpaRepositories(basePackages = "org.baeldung.repository")
@PropertySource("persistence-generic-entity.properties")
@EnableTransactionManagement
public class H2JpaConfig {
    // ...
}

Далее мы можем определить DataSource bean-компонент на основе этих свойств в классе @Configuration, который загружает наш persistence-generic-entity.properties в качестве источника свойств:

Более подробный пример этой конфигурации см. в нашей предыдущей статье о Self -содержащее тестирование с базой данных в оперативной памяти, раздел «Конфигурация JPA».

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Application.class, H2JpaConfig.class})
public class SpringBootH2IntegrationTest {
    // ...
}

Затем мы можем создать тест JUnit, аналогичный предыдущему, за исключением того, что он будет загружать наш класс конфигурации:

5. Использование профилей Spring

Еще один способ настроить отдельный источник данных для тестирования: используя Spring Profiles для определения bean-компонента DataSource, который доступен только в тестовом профиле.

Для этого мы можем использовать файл .properties, как и раньше, или мы можем записать значения в самом классе.

@Configuration
@EnableJpaRepositories(basePackages = {
  "org.baeldung.repository",
  "org.baeldung.boot.repository"
})
@EnableTransactionManagement
public class H2TestProfileJPAConfig {

    @Bean
    @Profile("test")
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("org.h2.Driver");
        dataSource.setUrl("jdbc:h2:mem:db;DB_CLOSE_DELAY=-1");
        dataSource.setUsername("sa");
        dataSource.setPassword("sa");

        return dataSource;
    }
    
    // configure entityManagerFactory
    // configure transactionManager
    // configure additional Hibernate properties
}

Давайте определим bean-компонент DataSource для тестового профиля в классе @Configuration, который будет загружен нашим тестом:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {
  Application.class, 
  H2TestProfileJPAConfig.class})
@ActiveProfiles("test")
public class SpringBootProfileIntegrationTest {
    // ...
}

Затем в тестовом классе JUnit нам нужно указать, что мы хотим использовать тест profile, добавив аннотацию @ActiveProfiles:

6. Заключение

В этом кратком руководстве мы рассмотрели несколько способов настройки отдельного источника данных для тестирования в Spring.