Spring Boot如何配置数据库连接避免单元测试失败?
解决Spring Boot测试阶段PostgreSQL连接失败问题
问题现象
执行mvn clean install时触发数据库连接错误:
org.postgresql.util.PSQLException: The connection attempt failed during Maven install
用-DskipTests仅能跳过安装阶段的错误,但执行mvn test时仍会出现相同问题。自动生成的@SpringBootTest测试类在加载应用上下文时引发该错误。
相关配置信息
项目依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <scope>runtime</scope> </dependency> ... </dependencies>
自动生成的测试类
package com.hamza.ince.bonptitcoinapi; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest class BonPtitCoinApiApplicationTests { @Test void contextLoads() { } }
主配置文件(application.properties)
spring.datasource.url=jdbc:postgresql://postgresql-api:5432/annonce_db?user=annonce_username&password=annonce_password spring.datasource.username= postgres spring.datasource.password= password spring.jpa.properties.hibernate.format_sql=true spring.jpa.properties.hibernate.show_sql=true spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.PostgreSQLDialect spring.datasource.driver-class-name=org.postgresql.Driver
解决方案
1. 修复数据源配置冲突
当前配置存在两处问题:
- URL中已经携带了
user和password参数,同时又单独配置了spring.datasource.username和spring.datasource.password,导致参数冲突 spring.datasource.username和spring.datasource.password的值前后有空格,会导致认证失败
修复方式二选一:
- 方式A:保留URL中的认证信息,删除单独的用户名/密码配置
spring.datasource.url=jdbc:postgresql://postgresql-api:5432/annonce_db?user=annonce_username&password=annonce_password # 移除以下两行 # spring.datasource.username= postgres # spring.datasource.password= password
- 方式B:移除URL中的认证参数,保留单独配置(注意去掉值的前后空格)
spring.datasource.url=jdbc:postgresql://postgresql-api:5432/annonce_db spring.datasource.username=postgres spring.datasource.password=password
2. 为测试环境配置独立嵌入式数据库
如果测试阶段不需要连接外部PostgreSQL,推荐使用H2嵌入式数据库,避免依赖外部服务:
- 添加H2测试依赖到pom.xml
<dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>test</scope> </dependency>
- 在
src/test/resources下创建application-test.properties,配置H2数据库:
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1 spring.datasource.driver-class-name=org.h2.Driver spring.datasource.username=sa spring.datasource.password= spring.jpa.hibernate.ddl-auto=create-drop spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
- 修改测试类,指定使用测试环境配置:
package com.hamza.ince.bonptitcoinapi; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles("test"); @SpringBootTest @ActiveProfiles("test") class BonPtitCoinApiApplicationTests { @Test void contextLoads() { } }
3. 跳过完整应用上下文加载(仅适用于简单测试)
如果你的测试不需要加载完整Spring上下文,可以修改@SpringBootTest的参数:
package com.hamza.ince.bonptitcoinapi; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE) class BonPtitCoinApiApplicationTests { @Test void contextLoads() { } }
或者如果只是测试简单逻辑,完全不需要Spring支持,直接去掉@SpringBootTest注解:
package com.hamza.ince.bonptitcoinapi; import org.junit.jupiter.api.Test; class BonPtitCoinApiApplicationTests { @Test void contextLoads() { } }
内容的提问来源于stack exchange,提问作者Hamza Ince
相关产品推荐
相关产品推荐

