Unitils: как он может получить свойства базы данных из Spring - PullRequest
1 голос
/ 21 февраля 2012

Я использую Unitils с пружиной для модульного тестирования. Я настроил Spring с источником данных, используя файл свойств.

Мой вопрос: как я могу использовать тот же источник данных или те же свойства для Unitils?

Unitils ожидает файл в classpath unitils.properties с параметрами конфигурации базы данных, такими как url, пользователь, пароль и драйвер.

Я пытался настроить Unitils, используя свойства, использованные в конфигурации Spring, как показано ниже, но он не работает.

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

Спасибо, Adi

Ответы [ 3 ]

1 голос
/ 22 февраля 2012

Райан отвечает также правильно и полезно, хотя я использовал другой подход.

Я расширил класс 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 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 голос
/ 21 февраля 2012

Одно потенциальное решение ... Вы могли бы сделать так, чтобы ваша конфигурация Spring считала параметры источника данных из unitils.properties, а не наоборот.Наверное, не идеал.

Я полагаю, что unitils использует пружину под крышками, поэтому вы можете также попытаться добавить свой источник данных в свои тесты unitils, используя @SpringApplicationContext.Если бы вы могли выяснить имя компонента bean источника данных, настроенного unitils, при его запуске, вы могли бы переопределить его в своем контексте (предполагая, что bean источника данных unitils создан до того, как другие весенние bean-компоненты могут / не могут быть истинными.)

например,

@SpringApplicationContext({"correctDataSourceContext.xml"})

РЕДАКТИРОВАТЬ: Еще один вариант, который обязательно сработает: https://stackoverflow.com/a/6561782/411229 В основном создайте экземпляр Unitils самостоятельно и установите свойства вручную.

0 голосов
/ 30 сентября 2014

Просто хочу добавить какую-то идею, и я не уверен, является ли это лучшей практикой или нет, поправьте меня, если что-то не так.

  • MyProject
    - 1008 * ЦСИ *
    - TestPackage
    --- BaseServiceTest.class
    --- BlogspotServiceTest.class
    - hibernate.cfg.xml
    - Веб
    - WEB-INF
    --- Blogspot-сервлет-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>

МОЙ файл 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 для загрузки источника данных и других конфигураций bean-компонентов на мой BaseClass, и вот как я его реализую.

Ниже: см. Учебник по Spring-Unitils для более подробной информации

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);
    }
}

ПРИМЕЧАНИЕ: Пожалуйста, создайте unitils.properties и unitils-local.properties внутри TestPackage, чтобы иметь возможность запускать программу.

Для объяснения @SpringBean и других аннотаций, пожалуйста, прочитайте:

Unitils-EasyMock

...