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

使用@SpringJUnitConfig替代@SpringBootTest时的依赖与配置异常问题

解决@SpringJUnitConfig替代@SpringBootTest时的Bean注入与属性解析问题

核心问题分析

替换后出现的一系列问题本质是**@SpringJUnitConfig与@SpringBootTest的启动逻辑差异**:

  • @SpringBootTest会自动触发组件扫描、加载Spring Boot自动配置、读取默认配置文件(application.yml/properties);
  • @SpringJUnitConfig仅负责加载指定的配置类,不会自动执行上述Spring Boot特有的初始化逻辑。

分步解决方案

1. 解决NoSuchBeanDefinitionException(无法注入@Service)

需要显式指定组件扫描范围,让Spring能找到DataMarshallerService:

  • 在测试类上添加@ComponentScan,指定目标Service所在的包;
  • 或者在自定义配置类中添加@ComponentScan,再通过@SpringJUnitConfig指定该配置类。

2. 解决属性解析失败(${sftp.in.port}无法解析)

@SpringJUnitConfig默认不支持YAML配置文件加载,也不会自动启用Spring Boot的属性解析机制,需手动配置:

  • 自定义YamlTestPropertySourceFactory来加载YAML文件;
  • 结合@SpringBootConfiguration或@EnableConfigurationProperties启用Spring Boot属性处理逻辑。

完整配置示例

方案一:测试类直接配置(推荐,更简洁)

import org.springframework.boot.test.context.SpringBootConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.test.context.TestPropertySource;

@SpringJUnitConfig
// 启用Spring Boot配置基础能力
@SpringBootConfiguration
// 扫描DataMarshallerService所在的包,替换为你的实际包路径
@ComponentScan(basePackages = "com.yourproject.service")
// 加载测试用YAML配置,指定自定义Factory处理YAML
@TestPropertySource(
    locations = "classpath:application-test.yml",
    factory = YamlTestPropertySourceFactory.class
)
public class DataMarshallerServiceTest {

    @Autowired
    private DataMarshallerService dataMarshallerService;

    // 测试方法...
}

自定义YAML属性源Factory

import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;

import java.io.IOException;
import java.util.Properties;

public class YamlTestPropertySourceFactory implements PropertySourceFactory {
    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
        YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
        factory.setResources(resource.getResource());
        Properties properties = factory.getObject();
        // 生成属性源名称,为空则用文件名
        String sourceName = name != null ? name : resource.getResource().getFilename();
        return new PropertiesPropertySource(sourceName, properties);
    }
}

方案二:自定义配置类(更精准控制)

如果需要更细粒度的配置控制,可以创建测试专属配置类:

// 测试配置类
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.boot.context.properties.EnableConfigurationProperties;

@Configuration
@ComponentScan(basePackages = "com.yourproject.service")
// 启用配置属性绑定(如果你的项目用了@ConfigurationProperties)
@EnableConfigurationProperties(SftpProperties.class)
// 加载YAML配置,指定自定义Factory
@PropertySource(
    value = "classpath:application-test.yml",
    factory = YamlTestPropertySourceFactory.class
)
public class TestAppConfig {
    // 若需手动注册属性解析器(Spring Boot 2.2+ 通常无需此步骤)
    /*
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertyConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }
    */
}

// 测试类
@SpringJUnitConfig(classes = TestAppConfig.class)
public class DataMarshallerServiceTest {
    @Autowired
    private DataMarshallerService dataMarshallerService;

    // 测试方法...
}

关键注意事项

  • 确保application-test.yml放置在src/test/resources目录下,保证能被类路径扫描到;
  • 若项目使用@ConfigurationProperties绑定属性,需确保对应的配置类被@EnableConfigurationProperties或@Component标记;
  • 如果不需要精准控制,也可以直接在@SpringJUnitConfig上添加@EnableAutoConfiguration,但会加载所有Spring Boot自动配置,可能失去使用@SpringJUnitConfig的轻量化意义。

内容的提问来源于stack exchange,提问作者Simeon Leyzerzon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 14:47:42