You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot测试报错:Failed to load ApplicationContext问题求助

问题描述

测试REST应用时遭遇错误,无法加载ApplicationContext,根源是无法用嵌入式数据库替换DataSource。

错误栈

java.lang.IllegalStateException: Failed to load ApplicationContext  at
org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:98)
at
org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:124)
at
org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:118)
at
org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
at
org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener.prepareTestInstance(SpringBootDependencyInjectionTestExecutionListener.java:43)
at
org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:248)
at
org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:138)
at
java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
at
java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
at
java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
at
java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
at
java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at
java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310)
at
java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
at
java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734)
at
java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
at java.base/java.util.Optional.orElseGet(Optional.java:364)  at
java.base/java.util.ArrayList.forEach(ArrayList.java:1511)  at
java.base/java.util.ArrayList.forEach(ArrayList.java:1511) Caused by:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'dataSourceScriptDatabaseInitializer'
defined in class path resource
[org/springframework/boot/autoconfigure/sql/init/DataSourceInitializationConfiguration.class]:
Unsatisfied dependency expressed through method
'dataSourceScriptDatabaseInitializer' parameter 0; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'dataSource': Invocation of init method
failed; nested exception is java.lang.IllegalStateException: Failed to
replace DataSource with an embedded database for tests. If you want an
embedded database please put a supported one on the classpath or tune
the replace attribute of @AutoConfigureTestDatabase.

相关代码

测试类代码

@DataJpaTest
@ActiveProfiles("test")
public class SaveServiceTest {

@Autowired
private MedsRepo medsRepo;

@Test
void testSaveMeds() {
    Meds meds = new Meds(50, "test med", "5,00$", "Flu", 500, "test date");
    Meds savedMed = medsRepo.save(meds);
    assertThat(savedMed).usingRecursiveComparison().ignoringFields("id").isEqualTo("meds");
}
}

SaveService代码

@Service
public class SaveService {

@Autowired
private MedsRepo medsRepo;

public String saveMeds(@RequestBody Meds meds) {
    medsRepo.save(meds);
    return "Saved Successfully";
 }
 }

MedsRepo代码

public interface MedsRepo extends JpaRepository<Meds,Long> {
 }

Meds实体类代码

@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Meds {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY )
private long id;

@Column
private String name;

@Column
private String price;

@Column
private String category;

@Column
private int pillNumber; 

@Column
private String date;
}

控制器代码

@RestController
public class Controller {

@Autowired
private MedsRepo medsRepo;

@Autowired
private SaveService saveService;

@Autowired
private UpdateService updateService;

@Autowired 
DeleteService deleteService;
     
@GetMapping("/medicines")
public List<Meds> getMedicine(){
    return medsRepo.findAll();
}

@PostMapping(value = "/save")
public String saveMeds(@RequestBody Meds meds){
    return saveService.saveMeds(meds);
}

@PutMapping(value = "/update/{id}")
public String updateMeds(@PathVariable long id, @RequestBody Meds meds){
    return updateService.updateMeds(id, meds);
}

@DeleteMapping("/delete/{id}")
public String deleteMeds(@PathVariable long id){
    return deleteService.deleteMeds(id);
}
}

解决方案

方案1:添加嵌入式数据库依赖

@DataJpaTest默认会尝试用嵌入式数据库(如H2、HSQLDB)做测试,若项目未引入相关依赖就会报错。在构建文件中添加H2依赖:

Maven

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>test</scope>
</dependency>

Gradle

testImplementation 'com.h2database:h2'

方案2:关闭数据源自动替换

如果测试需要用外部数据库而非嵌入式库,给测试类添加@AutoConfigureTestDatabase注解调整策略:

@DataJpaTest
@ActiveProfiles("test")
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
public class SaveServiceTest {
    // 原有测试代码不变
}

这样Spring Boot会直接使用test环境配置的数据源,不再尝试替换。

方案3:修正测试断言错误

测试类中的断言存在逻辑错误:isEqualTo("meds")是和字符串比较,实际应该和创建的meds对象比较,修改后:

assertThat(savedMed).usingRecursiveComparison().ignoringFields("id").isEqualTo(meds);

方案4:检查test环境配置

若已配置test环境数据源,确保application-test.properties/application-test.yml中的配置正确,且对应数据库驱动已引入依赖。例如MySQL配置:
application-test.properties:

spring.datasource.url=jdbc:mysql://localhost:3306/test_db
spring.datasource.username=root
spring.datasource.password=your_password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

同时添加MySQL驱动依赖(Maven):

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

内容的提问来源于stack exchange,提问作者Bernardo Alves

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 02:25:51