1. 概述
当测试依赖持久层(如JPA)的Spring应用时,我们通常希望为测试配置一个更轻量、更快的数据库,而非生产环境使用的数据库。这能显著提升测试执行效率。
在Spring中配置数据源需要定义一个DataSource
类型的bean。我们可以手动创建,或在Spring Boot中通过标准属性文件自动配置。
本文将介绍在Spring中为测试配置独立数据源的几种实用方法。
2. Maven依赖
我们将创建一个使用Spring JPA的Spring Boot应用,需要添加以下依赖:
<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>
最新版本可在Maven Central下载:
下面我们探讨几种测试数据源配置方案:
3. 在Spring Boot中使用标准属性文件
Spring Boot默认加载src/main/resources
下的application.properties
文件。若要为测试使用不同配置,只需在src/test/resources
创建同名文件覆盖即可。
测试用的application.properties
应包含数据源配置属性(前缀为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会自动根据这些属性创建DataSource
bean。
定义一个简单的JPA实体和仓库:
@Entity
public class GenericEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String value;
//标准构造器、getter/setter
}
public interface GenericEntityRepository
extends JpaRepository<GenericEntity, Long> { }
编写仓库测试类(需添加@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. 使用自定义属性文件
若不想使用标准属性文件或未使用Spring Boot,可创建自定义.properties
文件,然后在@Configuration
类中读取并创建数据源。
将自定义文件(如persistence-generic-entity.properties
)放在:
src/main/resources
(生产环境)src/test/resources
(测试环境)
测试环境配置示例(H2内存数据库):
jdbc.driverClassName=org.h2.Driver
jdbc.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
jdbc.username=sa
jdbc.password=sa
在配置类中加载该文件并创建数据源:
@Configuration
@EnableJpaRepositories(basePackages = "org.baeldung.repository")
@PropertySource("persistence-generic-entity.properties")
@EnableTransactionManagement
public class H2JpaConfig {
// 完整配置参考:[内存数据库自包含测试](/spring-jpa-test-in-memory-database)的JPA配置章节
}
编写测试类(需加载自定义配置类):
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Application.class, H2JpaConfig.class})
public class SpringBootH2IntegrationTest {
// 测试代码同上
}
5. 使用Spring Profiles
通过Spring Profiles定义仅在test
profile下生效的数据源bean:
@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;
}
// 配置entityManagerFactory
// 配置transactionManager
// 配置额外Hibernate属性
}
在测试类中激活test
profile:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {
Application.class,
H2TestProfileJPAConfig.class})
@ActiveProfiles("test")
public class SpringBootProfileIntegrationTest {
// 测试代码同上
}
6. 结论
本文介绍了在Spring中为测试配置独立数据源的三种主流方案:
✅ 标准属性文件覆盖(Spring Boot默认机制)
✅ 自定义属性文件(灵活性强)
✅ Spring Profiles(环境隔离最佳实践)
⚠️ 踩坑提醒:测试数据源配置错误可能导致测试环境污染生产数据库,务必确保测试配置与生产环境隔离。
完整示例代码请参考GitHub仓库。