【问题标题】:Using actual properties file from src/main/resources with Spring @PropertySource in JUnit test在 JUnit 测试中使用来自 src/main/resources 的实际属性文件和 Spring @PropertySource
【发布时间】:2020-07-20 16:15:29
【问题描述】:

我正在尝试通过使用 H2 数据库而不是实际数据库来对 DAO 类进行单元测试。我在尝试让我的测试用例使用 src/main/resources/properties/ 文件夹中存在的属性文件时遇到问题:

测试类

@RunWith(SpringJUnit4ClassRunner.class)
@PropertySource("classpath:properties/common.properties")
@ContextConfiguration(locations = { "/spring/common-context.xml" })
public class ConfigDAOImplTest {

    @Autowired
    private ConfigDAOImpl configDAO;

    @Spy
    private ContextParamDAO contextParamDAO = new ContextParamDAOImpl();

    private static final String SCHEMA_CONFIG = "classpath:data/CONFIG_SCHEMA.sql";
    private static final String DATA_CONFIG = "classpath:data/CONFIG_DATA.sql";

    @Before
    public void init() {
        MockitoAnnotations.initMocks(this);

        DataSource dataSource = new EmbeddedDatabaseBuilder()
                .setType(EmbeddedDatabaseType.H2)
                .addScript(SCHEMA_CONFIG)
                .addScript(DATA_CONFIG)
                .build();

        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

        //override the jdbcTemplate for the test case    
        configDAO.setJdbcTemplate(jdbcTemplate);
        configDAO.setContextParamDAO(contextParamDAO);


    }

    //.. more coode
}

common-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:batch="http://www.springframework.org/schema/batch"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd        
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-2.5.xsd      
        http://www.springframework.org/schema/batch 
        http://www.springframework.org/schema/batch/spring-batch.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="commonAppProperties"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="ignoreResourceNotFound" value="true" />
        <property name="ignoreUnresolvablePlaceholders" value="true" />
        <property name="locations">
            <list>
                <value>file:${conf_folder_path}/common.properties</value>
            </list>
        </property>
    </bean>

    <bean id="configDAO"
        class="com.myproject.common.dataaccess.impl.ConfigDAOImpl" scope="step">
        <property name="jdbcTemplate" ref="jdbcTemplate" />
        <property name="corePoolSize" value="${threadpool.size}"/>
    </bean>
</beans>

当我运行测试类时,我得到以下异常:

Caused by: org.springframework.beans.TypeMismatchException: Failed to convert property value of type 'java.lang.String' to required type 'int' for property 'corePoolSize'; nested exception is java.lang.NumberFormatException: For input string: "${threadpool.size}"

测试用例无法找到所需属性的一个原因是:

  1. PropertyPlaceholderConfigurer bean 指的是 {conf_folder_path}/common.properties 这是路径 src/main/resources/properties/common.properties 被 Maven 构建系统复制到。
  2. 但是,在 Eclipse 中,没有 {conf_folder_path},因为它是由 Maven 创建的。

问题: 假设上述原因是问题的根本原因,考虑到 Spring 上下文中引用的路径与源代码。

【问题讨论】:

  • 你应该从 src/main/resources/properties/common.properties 复制文件并粘贴到 src/test/resources/properties/common.properties @Ping
  • @Lemmy 我可以。但随后我将使用实际属性文件的“副本”。这更像是一个集成测试,我想使用“实际”属性文件而不是创建一个副本并使用它。 (编辑,将其复制到测试文件夹并没有解决问题。正如我的问题中所解释的, conf_folder_path 是弹簧上下文正在寻找属性的位置“
  • 你试过@TestPropertySource吗?
  • @Lemmy 我没有使用 Spring Boot :(
  • @TestPropertySource 不是来自 Spring Boot。它位于 Spring Framework 的核心 spring-test 工件中。

标签: java spring junit properties spring-test


【解决方案1】:

你可以创建这样的东西:

@Configuration
public class TestConfiguration {

    private static final Logger log = LoggerFactory.getLogger(TestConfiguration.class);

    @Autowired
    private Environment env;

    /**
     * This bean is necessary in order to use property file from src/main/resources/properties
     * @param env environment
     * @return property source configurator with correct property file
     */
    @Bean
    public PropertySourcesPlaceholderConfigurer placeholderConfigurerDev(ConfigurableEnvironment env) {
        final String fileName = "common.properties";
        Path resourceDirectory = Paths.get("src","main","resources", "properties");
        String absolutePath = resourceDirectory.toFile().getAbsolutePath();
        final File file = new File(absolutePath.concat("/").concat(fileName));
        if (file.exists()) {
            try {
                MutablePropertySources sources = env.getPropertySources();
                sources.addFirst(new PropertiesPropertySource(fileName, PropertiesLoaderUtils.loadAllProperties(file.getName())));
            } catch (Exception ex) {
                log.error(ex.getMessage(), ex);
                throw new RuntimeException(ex.getMessage(), ex);
            }
        }
        this.env = env;
        return new PropertySourcesPlaceholderConfigurer();
    }

【讨论】:

  • 给我指路很有用。我知道我需要创建自己的 PropertySourcePLaceHolder 。我赞成你的回答;但是,我的应用程序主要使用 XML 配置。使用您的答案,我能够提出一种 XML 方法来解决此问题。
【解决方案2】:

感谢@Lemmy 提供有关如何解决此问题的指导。

我的最终解决方案是创建一个新的common-test-context.xml 文件,我可以在其中查找类路径的属性文件夹中的属性文件。我将此文件放在src/test/resources/spring 文件夹中,并从src/main/resources/spring 文件夹中导入实际的common-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:batch="http://www.springframework.org/schema/batch"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd        
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-2.5.xsd      
        http://www.springframework.org/schema/batch 
        http://www.springframework.org/schema/batch/spring-batch.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <import resource="classpath*:/spring/common-context.xml" />


    <bean id="commonAppProperties"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="ignoreResourceNotFound" value="true" />
        <property name="ignoreUnresolvablePlaceholders" value="true" />
        <property name="locations">
            <list>
                <value>classpath:/properties/common.properties</value>
            </list>
        </property>
    </bean>

</beans>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-29
    • 2014-09-21
    • 2020-07-24
    • 1970-01-01
    • 2012-03-26
    • 2013-10-21
    • 1970-01-01
    • 2016-01-03
    相关资源
    最近更新 更多