Настройка отдельного источника данных Spring для тестов

Настройка отдельного источника данных Spring для тестов

1. обзор

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

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

В этом кратком руководстве мы рассмотримseveral ways to configure a separate data source for testing in Spring.

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

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


    org.springframework.boot
    spring-boot-starter-data-jpa
    2.1.3.RELEASE


    com.h2database
    h2
    1.4.197


    org.springframework.boot
    spring-boot-starter-test
    2.1.3.RELEASE

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

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

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

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

Если мы хотим использовать разные свойства для тестов, мы можем переопределить файл свойств в папкеmain, поместив другой файл с тем же именем в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 { }

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

@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());
    }
}

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

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

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

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

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

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

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

Более подробный пример этой конфигурации см. В нашей предыдущей статье оSelf-contained testing with an in-memory database, раздел «Конфигурация JPA».

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

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

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

Другой способ настроить отдельныйDataSource для тестирования - использовать профили Spring для определения bean-компонентаDataSource, который доступен только в профилеtest.

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

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

@Configuration
@EnableJpaRepositories(basePackages = {
  "org.example.repository",
  "org.example.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
}

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

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

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

В этом кратком руководстве мы увидели несколько способов, с помощью которых мы можем настроить отдельныеDataSource для тестирования в Spring.

Как всегда, полный исходный код примеров можно найтиover on GitHub.