2012-02-21 86 views
1

我使用Unitils與Spring進行單元測試。我使用屬性文件爲數據源配置了Spring。Unitils:它如何從Spring獲取數據庫屬性

我的問題是我如何使用相同的數據源或Unitils相同的屬性?

單元需要類路徑unitils.properties中的文件,其中包含數據庫配置參數,如url,用戶,密碼和驅動程序。

我試過使用下面的Spring配置中使用的屬性來配置Unitils,但它不起作用。

database.driverClassName=${jdbc.driver.class} 

感謝, 阿迪

回答

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 
1

一個潛在的解決方案......你可以有你的Spring配置從unitils.properties讀,而不是周圍的其他方法的數據源參數。可能不理想。

我相信單元正在使用彈簧,因此您可能還會嘗試使用@SpringApplicationContext在單元測試中添加數據源上下文。如果您可以在啓動時找出由單元設置的數據源bean的名稱,則可以在您的上下文中重寫它(假設單元數據源bean是在其他spring bean可能會/可能不會是真實的之前創建的)。

eg

@SpringApplicationContext({"correctDataSourceContext.xml"})

編輯:https://stackoverflow.com/a/6561782/411229 基本上實例Unitils自己和手動設置的屬性:那肯定會工作的另一個選擇。

0

只是想添加一些想法和即時消息不知道如果這是一個最佳實踐或沒有這麼糾正我,如果有錯誤的東西。

  • MYPROJECT
    - SRC
    --TestPackage
    --- BaseServiceTest.class
    --- BlogspotServiceTest.class
    --hibernate.cfg。XML
    - 網絡
    --Web-INF
    --- BlogSpot的-的servlet-的test.xml
    ---jdbc-test.properties

在我的情況,我用我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> 

MY 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說明,並標註請閱讀:

Unitils-EasyMock