2
votes

I have a small Spring web application, with the typical MVC Service DAO JPA/Hibernate Persistence Layer architecture. In production, I use a JTA-like persistence unit. The DAO is injected with an instance of the EntityManager via @PersistenceContext by the container. All is fine.

Now, I want to test my DAO implementations using an in-memory database (outside of a container on my local pc). I could manually create a RESOURCE_LOCAL based EntityManager. But how can I have it injected in my DAO implementations automatically?

I have seen this question and it suggests that it is possible with Spring. But how?

Of course, for unit testing, I could use new MyDAOImpl() and inject the EntityManager myself, but later, I will want to test my services which are injected with DAO implementations. I would like to avoid having to wire everything myself... Is this possible?

1

1 Answers

1
votes

In our project, we define a different unit-testing-config.xml that has the datasource bean defined to point the in-memory database as follows:

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="org.hsqldb.jdbc.JDBCDriver" />
        <property name="jdbcUrl"
                value="jdbc:hsqldb:file:/data/data.db" />
        <property name="user" value="sa" />
        <property name="password" value="" />
        <property name="initialPoolSize" value="1" />
        <property name="minPoolSize" value="1" />
        <property name="maxPoolSize" value="50" />
        <property name="maxIdleTime" value="240" />
        <property name="checkoutTimeout" value="60000" />
        <property name="acquireRetryAttempts" value="0" />
        <property name="acquireRetryDelay" value="1000" />
        <property name="numHelperThreads" value="1" />
</bean>

The normal entityManagerFactory defintion as follows will use the above datasource bean:

<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="persistenceUnitName" value="myDoctorPersistenceUnit" />
    <property name="loadTimeWeaver">
        <bean
            class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
    </property>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="showSql" value="true" />
            <property name="generateDdl" value="true" />
            <property name="databasePlatform" value="org.hibernate.dialect.HSQLDialect" />
        </bean>
    </property>
    <property name="jpaDialect" ref="jpaDialect" />
</bean>

And we run our TestSuite using the following annotations:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations ={ "/spring-configuration/test-spring.xml" })

Hope this helps!