Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to provide a test datasource in spring?

I'm studying Spring with Hibernate now. I have a POJO model class annotated with Hibernate annotations called Person, PersonDao interface and it's hibernate implementation and a PersonService class. I'm using annotations so they aren't defined as beans in my spring-config.xml. Now I want to write some JUnit4 tests for my PersonService class, but I want to use different database while testing. Here is my spring-config.xml

<context:component-scan base-package="org.example" />
<tx:annotation-driven />

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost/example" />
    <property name="username" value="root" />
    <property name="password" value="pwd" />
</bean>

<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.hbm2ddl.auto">update</prop>
        </props>
    </property>
    <property name="annotatedClasses">
        <list>
            ...
        </list>
    </property>
</bean>

And I want in my tests the jdbc:mysql://localhost/example_test database to be used. How do I achieve that?

like image 559
Vadym Kovalenko Avatar asked Jan 23 '14 16:01

Vadym Kovalenko


2 Answers

  • Move jdbc:mysql://localhost/example to configuration file (db.properties)

    database.uri=jdbc:mysql://localhost/example

  • Put this file somewhere in classpath (i.e. src/main/resources)

  • Set up property placeholder and use database URI property key in Spring context

    <context:property-placeholder location="classpath:db.properties" />
    ...
    <property name="url" value="${database.uri}" />
    
  • Create configuration file with the same name in test classpath (src/test/resources)

  • Change database URI property to test value (jdbc:mysql://localhost/example_test)

    database.uri=jdbc:mysql://localhost/example_test

Profit

like image 88
hoaz Avatar answered Nov 01 '22 13:11

hoaz


Extract definition of dataSource into separate XML file and provide different versions of that file when creating application contexts for test and production (i.e., spring-config.xml and datasource-prod.xml for production and spring-config.xml and datasource-test.xml for test).

Alternatively, you can use profiles to distinguish between test and production environments while using the same set of config files for both.

Yet another approach is to keep common definition of dataSource but externalize its properties into property files. But it won't allow you to use completely different definitions for different environments (for example, connection pool in production and simple DriverManagerDataSource for tests).

like image 40
axtavt Avatar answered Nov 01 '22 14:11

axtavt