Spring Boot单元测试:如何Mock @Value属性并注入配置值?
解决Spring Boot单元测试中@Value私有字段注入失败的问题
你的测试代码使用了Mockito的@InjectMocks注解,它仅负责创建CardService实例并注入Mock依赖,但不会触发Spring的@Value属性注入逻辑,因此maxTransactions会使用int类型的默认值0。以下是几种可行的解决方案:
方案一:使用Spring Boot测试框架加载完整上下文
通过@SpringBootTest注解启动Spring上下文,让Spring自动处理@Value的属性注入。如果CardService没有其他依赖,直接用@Autowired注入实例即可;若有需要Mock的依赖,配合@MockBean使用。
示例代码:
import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import static org.junit.jupiter.api.Assertions.assertTrue; @SpringBootTest class CardServiceTest { @Autowired private CardService service; @Test void testAddTransaction(){ Transaction transaction = new Transaction(); transaction.value = 10; assertTrue(service.addTransaction(transaction)); } }
如果需要指定测试专用配置文件,可添加@TestPropertySource:
@SpringBootTest @TestPropertySource(locations = "classpath:test-application.properties") class CardServiceTest { // 测试代码不变 }
方案二:手动注入私有字段(纯单元测试,不加载Spring上下文)
使用Spring提供的ReflectionTestUtils工具类,直接设置私有字段的值,无需依赖Spring上下文,适合快速的纯单元测试。
示例代码:
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.test.util.ReflectionTestUtils; import java.util.Properties; import java.io.IOException; import static org.junit.jupiter.api.Assertions.assertTrue; class CardServiceTest { private CardService service; @BeforeEach void setUp() throws IOException { service = new CardService(); // 方式1:直接指定测试值 // ReflectionTestUtils.setField(service, "maxTransactions", 20); // 方式2:从application.properties读取配置值 Properties props = new Properties(); props.load(getClass().getClassLoader().getResourceAsStream("application.properties")); int maxTransactions = Integer.parseInt(props.getProperty("max_transactions")); ReflectionTestUtils.setField(service, "maxTransactions", maxTransactions); } @Test void testAddTransaction(){ Transaction transaction = new Transaction(); transaction.value = 10; assertTrue(service.addTransaction(transaction)); } }
方案三:轻量加载Spring配置(仅处理属性注入)
如果不想加载完整的Spring Boot上下文,可使用@ExtendWith(SpringExtension.class)配合@TestPropertySource,让Spring仅处理属性注入逻辑,兼顾测试速度和配置加载。
示例代码:
import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.context.TestPropertySource; import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.assertTrue; @ExtendWith(SpringExtension.class) @TestPropertySource("classpath:application.properties") class CardServiceTest { @Autowired private CardService service; @Test void testAddTransaction(){ Transaction transaction = new Transaction(); transaction.value = 10; assertTrue(service.addTransaction(transaction)); } }
内容的提问来源于stack exchange,提问作者Cesare Moiola
相关产品推荐
相关产品推荐

