我正在使用Unitils和Spring进行单元测试。我使用属性文件为Spring配置了数据源。
我的问题是如何为Unitils使用相同的数据源或相同的属性?
Unitils期望classpath unitils.properties中的文件包含数据库配置参数,如url,user,password和driver。
我尝试使用Spring配置中使用的属性配置Unitils,但它不起作用。
database.driverClassName=${jdbc.driver.class}
谢谢, 阿迪
答案 0 :(得分:1)
一个可能的解决方案......您可以让您的Spring配置从unitils.properties读取其数据源参数,而不是相反。可能不理想。
我相信unitils正在使用spring,因此您也可以尝试使用@SpringApplicationContext
在unitils测试中添加数据源上下文。如果你可以在启动时通过unitils找出数据源bean设置的名称,你可以在你的上下文中覆盖它(假设在其他spring bean之前创建unitils数据源bean可能/可能不是真的。)< / p>
e.g。
@SpringApplicationContext({"correctDataSourceContext.xml"})
编辑:肯定会有效的另一种选择:https://stackoverflow.com/a/6561782/411229 基本上自己实例化Unitils并手动设置属性。
答案 1 :(得分:1)
我扩展了类PropertiesDataSourceFactory
ro覆盖方法如下:
public class UnitilsDataSourceFactory extends PropertiesDataSourceFactory {
@Override
public void init(Properties configuration) {
try {
String[] configFiles = new String[] { "applicationContext-test.xml" };
BeanFactory factory = new ClassPathXmlApplicationContext(configFiles);
SystemPropertiesReader systemPropertiesReader = (SystemPropertiesReader) factory.getBean("systemPropertiesReader");
Properties loadProperties = systemPropertiesReader.loadProperties();
super.init(loadProperties);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public DataSource createDataSource() {
DataSource dataSource = super.createDataSource();
return dataSource;
}
}
并且还将SystemPropertiesReader编写为:
public class SystemPropertiesReader {
private Collection<Resource> resources;
public void setResources(final Collection<Resource> resources) {
this.resources = resources;
}
public void setResource(final Resource resource) {
resources = Collections.singleton(resource);
}
@PostConstruct
public Properties loadProperties() throws Exception {
final Properties systemProperties = System.getProperties();
for (final Resource resource : resources) {
final InputStream inputStream = resource.getInputStream();
try {
systemProperties.load(inputStream);
} finally {
//
}
}
return systemProperties;
}
}
并添加了一个带有属性文件的bean:
<bean id="systemPropertiesReader" class="uk.co.friendslife.eventmanager.domain.dao.SystemPropertiesReader">
<property name="resource">
<value>classpath:/META-INF/em/config/eventmanager_${database_name_lower}.properties</value>
</property>
</bean>
将以下内容添加到unitils.properties:
org.unitils.database.config.DataSourceFactory.implClassName=x.y.UnitilsDataSourceFactory
答案 2 :(得分:0)
只是想添加一些想法,我不确定这是否是最佳做法,如果错误的话,请纠正我。
就我而言,我使用blogspot-servlet-test.xml来调用或创建数据源
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
.... some bean configuration
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="file:web/WEB-INF/jdbc.properties"/>
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.databaseurl}"
p:username="${jdbc.username}"
p:password="${jdbc.password}"/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:hibernate.cfg.xml"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<!-- DAO'S -->
<bean id="blogspotDAO" class="package.BlogspotDAOImpl"/>
<!-- SERVICES -->
<bean id="blogspotService" class="package.BlogspotServiceImpl"/>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
我的jdbc-test.properties文件
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.dialect=org.hibernate.dialect.MySQL5Dialect
jdbc.databaseurl=jdbc:mysql://127.0.0.1:3306/dbspringminiblogtest
jdbc.username=root
jdbc.password=
对于hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd//hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<mapping class="somePackage.entity.Author"/>
<!-- Other Entity Class to be mapped -->
</session-factory>
</hibernate-configuration>
我为我创建了BaseClass以减少创建多个@SpringApplicationContext注释,它还用于配置测试其他类所需的常用配置,只需对其进行扩展。
@SpringApplicationContext({"file:web/WEB-INF/blogspot-servlet-test.xml"})
public class BaseServiceTest extends UnitilsJUnit4 {
}
我使用@SpringApplicationContext在我的BaseClass上加载数据源和其他bean配置,这就是我实现它的方式。
下方:见Spring-Unitils Tutorial 了解更多详情
public class BlogspotServiceTest extends BaseServiceTest{
@Mock
@InjectInto(property = "blogspotDAO")
@SpringBean("blogspotDAO")
private BlogspotDAO blogspotDAOMock;
@TestedObject
@SpringBean("blogspotService")
private BlogspotService blogspotServiceMock;
@Test
public void testAddBlogSpot() {
assertNotNull("BlogspotService Not null",blogspotServiceMock);
}
}
注意:请在TestPackage中创建unitils.properties和unitils-local.properties以便能够运行该程序。
对于@SpringBean说明和其他注释,请阅读: