Spring Boot contextLoads()测试方法加载失败问题求助
Spring Boot测试contextLoads()失败:无法加载ApplicationContext及dataSourceScriptDatabaseInitializer Bean创建失败
报错信息
java.lang.IllegalStateException: 无法加载ApplicationContext,对应配置:[WebMergedContextConfiguration@37496720 testClass = com.cookbookbackend.CookbookBackendApplicationTests, locations = [], classes = [com.cookbookbackend.CookbookBackendApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceLocations = [], propertySourceProperties = ["org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@48aca48b, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@72e5a8e, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@6fdbe764, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@298a5e20, org.springframework.boot.test.context.SpringBootTestAnnotation@2b8500b9], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
创建名为'dataSourceScriptDatabaseInitializer'的Bean失败,该Bean定义于类路径资源[org/springframework/boot/autoconfigure/sql/init/DataSourceInitializationConfiguration.class]
相关配置与代码
application.properties
spring.datasource.url=${DB_URL} spring.datasource.username=${DB_USERNAME} spring.datasource.password=${DB_PASSWORD} spring.jpa.database-platform = org.hibernate.dialect.PostgreSQLDialect spring.jpa.hibernate.ddl-auto = none spring.jpa.hibernate.show-sql=true
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.1.2</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.</groupId> <artifactId>cookbook-backend</artifactId> <version>0.0.1-SNAPSHOT</version> <name>cookbook-backend</name> <description>Demo project for Spring Boot</description> <properties> <java.version>17</java.version> </properties> <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.postgresql</groupId> <artifactId>postgresql</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.hamcrest</groupId> <artifactId>hamcrest-core</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
ApplicationTests.java
import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest class CookbookBackendApplicationTests { @Test void contextLoads() { } }
问题原因
应用运行正常是因为生产/开发环境已配置DB_URL、DB_USERNAME、DB_PASSWORD这三个环境变量,但测试环境未加载到这些变量,导致Spring无法初始化数据源,进而触发dataSourceScriptDatabaseInitializer Bean创建失败,最终ApplicationContext加载失败。
解决方法
方法1:为测试环境配置数据库信息
在src/test/resources目录下创建application-test.properties,填入测试用的数据库连接信息(可用真实测试库或嵌入式数据库如H2):
# 示例:使用H2嵌入式数据库 spring.datasource.url=jdbc:h2:mem:testdb spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password= spring.jpa.database-platform=org.hibernate.dialect.H2Dialect spring.sql.init.mode=always
同时在测试类上添加@ActiveProfiles("test"):
import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; @SpringBootTest @ActiveProfiles("test") class CookbookBackendApplicationTests { @Test void contextLoads() { } }
如果用H2,需要在pom.xml中添加H2依赖:
<dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>test</scope> </dependency>
方法2:禁用数据库初始化
在src/test/resources/application.properties中添加配置,阻止Spring Boot执行数据库初始化脚本:
spring.sql.init.mode=never
方法3:模拟数据源相关Bean
使用@MockBean模拟DataSourceScriptDatabaseInitializer,避免Spring依赖真实数据库:
import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.sql.init.datasource.DataSourceScriptDatabaseInitializer; @SpringBootTest class CookbookBackendApplicationTests { @MockBean private DataSourceScriptDatabaseInitializer dataSourceScriptDatabaseInitializer; @Test void contextLoads() { } }
内容的提问来源于stack exchange,提问作者Strugglingperson
相关产品推荐
相关产品推荐

