Spring Boot测试加载ApplicationContext失败及配置问题求助
Spring Boot测试ApplicationContext加载失败及配置疑问
问题场景
我在Spring Boot项目中对Service类编写简单测试,测试代码如下:
@RunWith(SpringRunner.class) @SpringBootTest class DailyMoodLogServiceImplTest { @MockBean DailyMoodLogRepository moodLogRepository; @BeforeEach public void setUp(){ List<DailyMoodLog> dailyMoodSample = List.of(new DailyMoodLog(1L, "Good", Timestamp.valueOf(LocalDateTime.now()), "United States", new Users(1L, "John", "London")), new DailyMoodLog(2L, "Bad", Timestamp.valueOf(LocalDateTime.now() ), "Canada", new Users(2L, "Anthony", "Wilkins"))); Mockito.when(moodLogRepository.findAll()).thenReturn(dailyMoodSample); } @Test void getAllDailyMoods() { assertEquals(2, moodLogRepository.findAll().size()); } }
执行时收到Failed to load ApplicationContext错误,排查发现根源是application.yml中spring.profiles配置过时,需替换为spring.config.activate.on-profile。初始application.yml配置如下:
server: port: 8082 spring: profiles: active: main --- spring: profiles: main datasource: driver-class-name: com.mysql.jdbc.Driver password: ${SPRING_DATASOURCE_PASSWORD} url: ${SPRING_DATASOURCE_URL} username: ${SPRING_DATASOURCE_USERNAME} jpa: hibernate: ddl-auto: update show-sql: true
调整配置后仍报相同类型错误,同时有两个疑问:
- 将数据源的password、url、username配置在VM选项是否正确?
- 配置文件中的占位符是否可通过环境变量、程序参数或VM选项配置,仅用VM选项是否可行?
问题分析与解答
1. 配置文件修复
你的application.yml存在两个问题:
- 分块定义环境时的
spring.profiles: main属于过时配置,需替换为spring.config.activate.on-profile: main; - YAML缩进错误,分块后的
spring节点缩进过多,YAML对缩进敏感,会导致配置解析失败。
正确的配置文件如下:
server: port: 8082 spring: profiles: active: main # 该属性未过时,用于指定激活的环境 --- spring: config: activate: on-profile: main # 替换过时的spring.profiles配置,标识当前块所属环境 datasource: driver-class-name: com.mysql.cj.jdbc.Driver # 注意:旧版com.mysql.jdbc.Driver已废弃,推荐使用新版 password: ${SPRING_DATASOURCE_PASSWORD} url: ${SPRING_DATASOURCE_URL} username: ${SPRING_DATASOURCE_USERNAME} jpa: hibernate: ddl-auto: update show-sql: true
2. 关于VM选项配置数据源信息
- 将数据源的敏感信息配置在VM选项是可行且合理的,能避免敏感信息硬编码在配置文件中,VM选项格式为
-DSPRING_DATASOURCE_URL=jdbc:mysql://localhost:3306/your_db,同理设置username和password。 - 配置文件中的占位符支持通过环境变量、程序参数、VM选项三种方式赋值,仅用VM选项完全可行。Spring Boot属性加载优先级中,VM参数(系统属性)优先级高于环境变量和配置文件,若多来源配置冲突,VM选项的值会覆盖其他配置。
3. 测试代码优化(可选)
当前测试直接验证Mock的Repository,未达到测试Service层的目的,建议注入Service类测试其业务逻辑:
@RunWith(SpringRunner.class) @SpringBootTest class DailyMoodLogServiceImplTest { @MockBean DailyMoodLogRepository moodLogRepository; @Autowired DailyMoodLogServiceImpl moodLogService; // 注入待测试的Service @BeforeEach public void setUp(){ List<DailyMoodLog> dailyMoodSample = List.of( new DailyMoodLog(1L, "Good", Timestamp.valueOf(LocalDateTime.now()), "United States", new Users(1L, "John", "London")), new DailyMoodLog(2L, "Bad", Timestamp.valueOf(LocalDateTime.now()), "Canada", new Users(2L, "Anthony", "Wilkins")) ); Mockito.when(moodLogRepository.findAll()).thenReturn(dailyMoodSample); } @Test void getAllDailyMoods() { assertEquals(2, moodLogService.getAllDailyMoods().size()); // 测试Service的业务方法 } }
内容的提问来源于stack exchange,提问作者Jschwery
相关产品推荐
相关产品推荐

