Spring Boot测试中@TestPropertySource与@Value无法加载配置问题
问题根源
你使用的MockitoExtension仅负责Mockito的Mock对象管理,不会启动Spring容器,因此@Value、@TestPropertySource这类Spring注解完全不起作用,自然无法注入配置属性。
最优解决方案
方案1:使用@SpringBootTest(推荐,适配Spring上下文场景)
替换Mockito扩展为Spring Boot测试注解,用@MockBean替代@Mock,让Spring管理Bean并处理属性注入:
@SpringBootTest @TestPropertySource(locations = "classpath:application-test.properties") class AccessTokenServiceTest { @MockBean private AccessTokenBlacklistRepository accessTokenBlacklistRepository; @MockBean private UserBlacklistRepository userBlacklistRepository; @MockBean private MessageService messageService; @Autowired private AccessTokenServiceImpl accessTokenService; // tests... }
Spring会启动轻量上下文,@Value能正常读取配置文件中的jwt.secret,同时@MockBean会替换容器中对应的真实Bean为Mock对象。
方案2:轻量Spring上下文(仅加载必要组件)
如果不想启动完整Spring Boot应用上下文,可以指定仅加载目标服务类,结合SpringExtension:
@ExtendWith(SpringExtension.class) @TestPropertySource(locations = "classpath:application-test.properties") @ContextConfiguration(classes = AccessTokenServiceImpl.class) class AccessTokenServiceTest { @MockBean private AccessTokenBlacklistRepository accessTokenBlacklistRepository; @MockBean private UserBlacklistRepository userBlacklistRepository; @MockBean private MessageService messageService; @Autowired private AccessTokenServiceImpl accessTokenService; // tests... }
@ContextConfiguration指定要加载的Bean,SpringExtension负责启动Spring上下文,同样能处理@Value注入。
方案3:手动注入属性(无需Spring上下文)
如果坚持只用Mockito,也可以手动读取配置文件并注入,比ReflectionTestUtils更规范:
@ExtendWith(MockitoExtension.class) class AccessTokenServiceTest { @Mock private AccessTokenBlacklistRepository accessTokenBlacklistRepository; @Mock private UserBlacklistRepository userBlacklistRepository; @Mock private MessageService messageService; @InjectMocks private AccessTokenServiceImpl accessTokenService; @BeforeEach void setUp() throws IOException { // 读取配置文件 Properties props = new Properties(); props.load(getClass().getClassLoader().getResourceAsStream("application-test.properties")); String jwtSecret = props.getProperty("jwt.secret"); // 用Spring的BeanWrapper注入属性 BeanWrapper wrapper = new BeanWrapperImpl(accessTokenService); wrapper.setPropertyValue("jwtSecret", jwtSecret); } // tests... }
这种方式不需要Spring上下文,BeanWrapper可以直接设置字段(即使私有),比反射工具类更符合Spring规范。
内容的提问来源于stack exchange,提问作者while1618
相关产品推荐
相关产品推荐

