«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.