Spring Boot测试用例中@Value注入属性为null的原因是什么
测试类上标注的@ExtendWith(MockitoExtension.class)是Mockito提供的JUnit 5扩展,仅会处理@Mock、@InjectMocks等Mockito体系的注解,不会启动Spring容器上下文。@Value是Spring提供的注入注解,只有当测试类实例由Spring容器管理时,才会被解析、加载application.properties中的配置完成字段赋值。当前测试实例由JUnit+Mockito直接创建,没有Spring参与注解处理流程,@Value标注的字段不会被任何逻辑赋值,自然保持Java对象默认的null值。
补充判断依据:如果Spring上下文正常启动但找不到对应配置项,会直接抛出无法解析占位符的异常,不会静默给字段赋值为null,你遇到的全字段null场景可以直接判定为Spring上下文未生效。
根据测试类型二选一即可:
集成测试方案(需要Spring加载配置、管理Bean)
替换测试类注解为Spring测试注解,SpringBoot项目直接使用@SpringBootTest启动测试上下文,同时将Mockito的@Mock替换为Spring提供的@MockBean,才能将Spring容器中的对应客户端Bean替换为Mock实例:@SpringBootTest public class CurrencyServiceTest { @MockBean private OpenExchangeRatesClient openExchangeRatesClient; @Value("${openexchangerates.app.id}") private String appId; @Value("${openexchangerates.currency.base}") private String base; // 测试逻辑 }非SpringBoot的纯Spring项目可以搭配
@ContextConfiguration指定需要加载的配置类、配置文件路径,构建最小化测试上下文。纯单元测试方案(无Spring依赖,执行速度快)
如果仅测试业务类本身的逻辑,不需要启动Spring容器,直接去掉@Value注解,手动给配置字段赋测试用固定值即可,不需要为了读取配置特意启动重量级Spring上下文拖慢测试速度:@ExtendWith(MockitoExtension.class) public class CurrencyServiceTest { @Mock private OpenExchangeRatesClient openExchangeRatesClient; // 手动赋值测试用配置,无需依赖Spring注入 private String appId = "test-app-id-001"; private String base = "USD"; // 测试逻辑 }
内容的提问来源于stack exchange,提问作者Федор Николаев

