You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot中如何将application.properties的@Value属性注入@InjectMocks对象

问题根因

  1. 你使用的PowerMockRunner默认不会启动Spring上下文,所有@Value注解都不会被Spring处理,测试类中定义的priorMap本身就是null,即便反射没有报错也无法注入有效值。
  2. 抛出的模块访问错误是高版本JDK(9+)的模块化限制导致的,PowerMock依赖的旧版XML解析库尝试访问JDK内部未导出的jdk.xml.internal包。
  3. 现有代码存在逻辑错误:BatchService中的priorMap是实例字段,不是静态字段,你在静态@BeforeClass方法中给类的静态字段赋值,就算没有报错,也不会生效到你测试用的batchService实例上。

可行解决方案(按推荐优先级排序)

方案1:直接手动赋值(最轻量,单元测试首选)

单元测试不需要加载Spring上下文,直接手动构造Map给实例赋值即可,完全避开兼容性问题:

@RunWith(PowerMockRunner.class)
@PrepareForTest({LogManager.class})
public class BatchServiceTest {

    @Mock
    private Repo repoMock;

    @InjectMocks
    private BatchService batchService;

    @Before
    public void setup() {
        // 构造和配置文件一致的映射
        Map<String, String> priorMap = Map.of("first", "1", "second", "2", "third", "3");
        // 因为priorMap是public修饰,直接赋值即可,无需反射
        batchService.priorMap = priorMap;
        // 如果priorMap是private,改用下面的反射写法即可
        // ReflectionTestUtils.setField(batchService, "priorMap", priorMap);
    }

    // 你的测试用例
}

方案2:手动加载配置文件(不想硬编码配置时使用)

如果不想把配置值硬编码在测试类中,可以手动读取classpath下的application.properties解析:

@RunWith(PowerMockRunner.class)
@PrepareForTest({LogManager.class})
public class BatchServiceTest {

    @Mock
    private Repo repoMock;

    @InjectMocks
    private BatchService batchService;

    @Before
    public void setup() throws IOException {
        // 加载配置文件
        Properties properties = new Properties();
        properties.load(getClass().getResourceAsStream("/application.properties"));
        String mappingStr = properties.getProperty("priority.mapping");
        
        // 解析映射字符串为Map,此处用Jackson做JSON解析,也可替换为其他JSON工具
        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, String> priorMap = objectMapper.readValue(
                mappingStr.replace("'", "\""), 
                new TypeReference<Map<String, String>>() {}
        );
        batchService.priorMap = priorMap;
    }

    // 你的测试用例
}

方案3:兼容Spring上下文+修复模块报错(必须用@Value注解时使用)

如果你一定要依赖Spring的@Value能力注入配置,需要调整测试类启动Spring上下文,同时修复JDK模块兼容问题:

  1. 调整测试类注解,用PowerMock委托SpringRunner启动上下文:
@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(SpringRunner.class)
@SpringBootTest
@PrepareForTest({LogManager.class})
public class BatchServiceTest {

    @Value("#{${priority.mapping}}")
    private Map<String, String> priorMap;

    @MockBean
    private Repo repoMock;

    @Autowired
    private BatchService batchService;

    @Before
    public void setup() {
        // 此时priorMap已经被Spring注入有效值,直接赋值即可
        batchService.priorMap = priorMap;
    }

    // 你的测试用例
}
  1. 解决JDK模块报错,给单元测试的JVM启动参数添加如下配置:
--add-exports java.xml/jdk.xml.internal=ALL-UNNAMED

如果是Maven项目,在pom.xml的surefire插件中统一配置:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
        <argLine>--add-exports java.xml/jdk.xml.internal=ALL-UNNAMED</argLine>
    </configuration>
</plugin>

内容的提问来源于stack exchange,提问作者Saqib Nisar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 23:27:03