Spring Boot JUnit测试无法获取@Value的原因及设置方法
问题产生原因
核心原因是@Value的属性注入是Spring容器在管理Bean生命周期时完成的,JUnit测试时拿不到注入值基本都是以下几种场景:
- 测试类没有添加Spring测试相关注解,没有启动Spring容器上下文,测试类实例没有被Spring托管,甚至是手动new出来的对象,自然不会执行
@Value解析注入逻辑,你给出的示例代码就属于这种情况,类上没有任何Spring相关注解,字段永远为null。 - Spring上下文启动了,但没有加载到对应配置文件,或者配置文件里不存在
${value}对应的配置键,也没有设置默认值,要么注入失败抛占位符解析异常,要么注入null。 - JUnit版本和Spring测试注解不匹配,比如JUnit 5环境错误使用JUnit4的
@RunWith注解,导致上下文启动异常,注入逻辑不生效。
正确设置、获取@Value属性值的方法
前提:所有测试类实例必须由Spring测试上下文创建,不要手动new测试类对象。
1. 加载项目全局配置(最常用)
如果${value}配置已经写在src/main/resources或src/test/resources下的application.yml/application.properties中,直接给测试类加对应注解启动Spring上下文即可。
- JUnit 5(Spring Boot 2.2+默认版本)写法:
import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.SpringBootTest; import static org.junit.jupiter.api.Assertions.*; @SpringBootTest // 该注解会自动启动Spring上下文,加载全局配置 class AppTest { @Value("${value}") private String value; @Test void testValueInjection() { // 此处value已经完成注入,可以直接使用 System.out.println("注入的配置值:" + value); assertNotNull(value); } }
- JUnit 4 写法:
import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import static org.junit.Assert.*; @RunWith(SpringRunner.class) @SpringBootTest public class AppTest { @Value("${value}") private String value; @Test public void testValueInjection() { System.out.println("注入的配置值:" + value); assertNotNull(value); } }
2. 测试场景单独指定配置值
如果不想依赖全局配置,只想给当前测试类单独设置@Value对应的属性值,可以通过注解参数直接指定,避免影响其他测试:
import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.TestPropertySource; import static org.junit.jupiter.api.Assertions.*; // 方式1:直接在@SpringBootTest中指定测试属性 @SpringBootTest(properties = "value=测试环境专属配置值") // 方式2:使用@TestPropertySource指定,优先级高于全局配置 // @TestPropertySource(properties = "value=测试环境专属配置值") // 方式3:指定测试专属的配置文件,比如加载src/test/resources下的test-config.properties // @TestPropertySource(locations = "classpath:test-config.properties") class AppTest { @Value("${value}") private String value; @Test void testValueInjection() { assertEquals("测试环境专属配置值", value); } }
3. 容错配置(可选)
如果配置键可能在某些环境不存在,可以给@Value设置默认值,避免上下文启动报错:
// 配置不存在时,默认注入"兜底默认值" @Value("${value:兜底默认值}") private String value;
常见避坑点
- 不要给
@Value标注的字段加static、final修饰,Spring无法对这类字段完成注入。 - 检查
@Value中占位符的拼写,必须和配置文件中的键完全一致,注意大小写、配置层级。 - 不要在测试类的构造方法、
@BeforeAll等静态初始化逻辑中调用注入的字段,此时字段还未完成注入,会拿到null。
内容的提问来源于stack exchange,提问作者suraj
相关产品推荐
相关产品推荐

