测试执行期间如何向Bean注入参数值?解决@Value占位符解析失败问题
代码场景
- 我在
Car类的构造方法中使用@Value注解将对应值作为参数注入,代码定义:@Service public class Car { public Car(@Value("${app.fabric.kafka.topics.sometopic}") final String topic) { } ... } GarageService类声明并使用Car实例作为依赖,代码定义:@Component @AllArgsConstructor public class GarageService { private @NonNull final Car; ... }GarageServiceTest测试类中,使用@InjectMocks实例化待测试对象,使用@Mock注入其他依赖的模拟实例,代码定义:@ContextConfiguration public class GarageServiceTest { @Mock private CarService carService; @InjectMocks private GarageService; ... }
异常表现
测试执行时抛出如下异常:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error when creating bean 'GarageService' defined in file [.../GarageService.class]: Unsatisfied dependency expressed through constructor parameter 1, ... nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'Car' defined in file [.../Car.class]: Unexpected exception during bean creation; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'app.fabric.kafka.topics.sometopic' in value "${app.fabric.kafka.topics.sometopic}".
问题原因
测试环境未加载到app.fabric.kafka.topics.sometopic对应的配置值,Spring尝试实例化真实Car Bean时,无法解析构造方法上的@Value占位符,最终导致依赖创建链路全部失败。
解决方案
- 纯Mockito单元测试场景
这类场景不需要加载Spring容器,问题根源是测试类同时标注了@ContextConfiguration,触发了Spring组件扫描,导致模拟注解失效,Spring转而尝试创建真实的CarBean。
调整操作:- 移除测试类上多余的
@ContextConfiguration注解 - 添加
@ExtendWith(MockitoExtension.class)注解,明确启用Mockito测试环境,跳过Spring容器初始化流程 - 修正
@Mock标注的依赖类型,和GarageService的实际依赖保持一致(即标注@Mock private Car car),让@InjectMocks能直接将模拟实例注入待测对象,不会触发真实Bean的创建流程。
- 移除测试类上多余的
- 需要加载Spring上下文的集成测试场景
若测试需要关联Spring容器,可从两个方向解决问题:- 补充测试环境的占位符配置:在测试类上添加
@TestPropertySource(properties = "app.fabric.kafka.topics.sometopic=test-topic-value"),直接给测试环境注入占位符对应的配置值 - 替换真实Car Bean:在测试上下文内定义模拟的Car Bean,避免触发真实Car的创建流程,示例配置代码:
@TestConfiguration static class MockCarConfig { @Bean public Car car() { return Mockito.mock(Car.class); } }
- 补充测试环境的占位符配置:在测试类上添加
内容的提问来源于stack exchange,提问作者Mar
相关产品推荐
相关产品推荐

