Spring PropertySource无法在JUnit Test中工作

时间:2015-03-15 15:50:11

标签: java spring java-ee junit spring-4

我在运行JUnit测试用例时遇到问题。

问题是, 当我将应用程序作为Web应用程序运行时,@PropertySource可以通过从xml文件中注入所有属性来正常工作,但是当我将应用程序作为JUnit运行时,我收到的错误是“无法解析占位符”。

的web.xml

<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:resources/applicationContext.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:resources/spring-mvc-context.xml</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

DAO课程

@Configuration
@PropertySource("classpath:resources/shore-dal_queries.xml")
public class SpringShoreDao extends SpringBaseDao implements ShoreDao {

    @Value("${shore.getAllShores}")
    private String getShoresQuery;

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Override
    public Optional<List<Shore>> getAllShores() throws DataAccessException {
        Optional<List<Shore>> shoreList = null;
        try {
            List<Shore> tempList = (getNamedParameterJdbcTemplate().query(getShoresQuery, new ShoreRowMapper()));
            shoreList = Optional.of(tempList);
        }
        catch (org.springframework.dao.DataAccessException e) {
        }
        return shoreList;
    }
}

XML文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
    <entry key="shore.getAllShores">
        <![CDATA[
            SELECT shoreID, shoreName, isActive, updatedBy, updatedDate, createdBy, createdDate
            FROM shore
        ]]>
    </entry>
</properties>

JUnit测试类

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
        "classpath:resources/applicationContext.xml",
        "classpath:resources/spring-mvc-context.xml"})
public class SpringShoreDaoTest {


    @Autowired
    ShoreDao shoreDao; 

    @Test
    public void testGetAllShores() throws DataAccessException {
        List<Shore> listShore= shoreDao.getAllShores();
        ............  
    }
}

弹簧MVC-context.xml中

  <annotation-driven />
    <context:annotation-config />
    <context:component-scan base-package="com.abc.him.utmc" />     
    <resources mapping="/resources/**" location="/resources/" />

    <beans:bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <beans:property name="messageConverters">
            <beans:list>
                <beans:ref bean="jsonMessageConverter"/>
            </beans:list>
        </beans:property>
    </beans:bean>

    <beans:bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
    </beans:bean> 

的applicationContext.xml

<context:annotation-config />
<context:property-placeholder location="classpath:resources/db.properties"/>
... DB related beans

当我运行JUnit测试文件时,我得到例外,

Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'shore.getAllShores' in string value "${shore.getAllShores}"

当我运行与Web应用程序相同的项目时,一切正常。

1 个答案:

答案 0 :(得分:1)

您可以在测试配置中定义PropertySourcesPlaceholderConfigurer并将resources/shore-dal_queries.xml设置为资源(有很好的示例here)。

所以尝试这样的事情:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class SpringShoreDaoTest {

    @Configuration
    @ImportResource({"classpath:resources/applicationContext.xml",
    "classpath:resources/spring-mvc-context.xml"})   
    static class someConfig {

        // because @PropertySource doesnt work in annotation only land
        @Bean
        public static PropertyPlaceholderConfigurer propConfig() {
            PropertyPlaceholderConfigurer ppc =  new PropertyPlaceholderConfigurer();
            ppc.setLocation(new ClassPathResource("resources/shore-dal_queries.xml"));
            return ppc;
        }

        @Bean
        public SpringShoreDao springShoreDao() {
            //probably you do not need this bean since you have component scan in applicationContext 
            return new SpringShoreDao();
        }
    }


    @Autowired
    SpringShoreDao springShoreDao; 

    @Test
    public void testGetAllShores() throws DataAccessException {
        List<Shore> listShore= shoreDao.getAllShores();
        ............  
    }
}