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.
Давайте рассмотрим несколько различных способов настройки источника данных
для тестирования.
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> { }
Далее давайте напишем тест 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.foreach.repository")
@PropertySource("persistence-generic-entity.properties")
@EnableTransactionManagement
public class H2JpaConfig {
// ...
}
Более подробный пример этой конфигурации можно найти в нашей предыдущей статье « Автономное тестирование с базой данных в памяти », раздел «Конфигурация JPA».
Затем мы можем создать тест JUnit
, аналогичный предыдущему, за исключением того, что он загрузит наш класс конфигурации:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Application.class, H2JpaConfig.class})
public class SpringBootH2IntegrationTest {
// ...
}
5. Использование профилей Spring
Другой способ настроить отдельный источник данных для тестирования — использовать профили Spring для определения bean-компонента DataSource
,
который доступен только в тестовом
профиле.
Для этого мы можем использовать файл .properties
, как и раньше, или мы можем записать значения в самом классе.
Давайте определим bean-компонент DataSource
для тестового
профиля в классе @Configuration
, который будет загружен нашим тестом:
@Configuration
@EnableJpaRepositories(basePackages = {
"org.foreach.repository",
"org.foreach.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
нам нужно указать, что мы хотим использовать тестовый
профиль, добавив аннотацию @ActiveProfiles
:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {
Application.class,
H2TestProfileJPAConfig.class})
@ActiveProfiles("test")
public class SpringBootProfileIntegrationTest {
// ...
}
6. Заключение
В этом кратком руководстве мы рассмотрели несколько способов настройки отдельного источника данных
для тестирования в Spring.
Как всегда, полный исходный код примеров можно найти на GitHub .