/java/

Hibernate3 Integration testing

2013-02-20 22:44:38

In this post you can find way how to test Dao. 1) First way. (junit+beta-config.xml+BetaPostDaoTest.java) You use existing DataBase to test your DAO. 2) Second way. (h2+virtual-config.xml+VirtualPostDaoTest.java) You use MemoryDataBase to test your DAO.

pom.xml


<dependency>
<groupid>com.h2database</groupid>
<artifactid>h2</artifactid>
<version>1.3.170</version>
</dependency>

<dependency>
<groupid>junit</groupid>
<artifactid>junit</artifactid>
<version>4.11</version>
</dependency>

beta-config.xml

<?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?>

<beans beans="" context="" http:="" schema="" spring-beans.xsd="" spring-context-3.1.xsd="" spring-tx-3.1.xsd&quot;="" tx="" www.springframework.org="" xmlns='"http://www.springframework.org/schema/beans"' xmlns:context='"http://www.springframework.org/schema/context"' xmlns:tx='"http://www.springframework.org/schema/tx"' xmlns:xsi='"http://www.w3.org/2001/XMLSchema-instance"' xsi:schemalocation='"http://www.springframework.org/schema/beans'>
<context:annotation-config></context:annotation-config>
<context:component-scan base-package='"com.louis.core"/'>
<!-- DataSource -->
<bean class='"org.springframework.jdbc.datasource.DriverManagerDataSource"' id='"dataSource"'>
<property name='"driverClassName"' value='"com.mysql.jdbc.Driver"'></property>
<property name='"url"' value='"jdbc:mysql://localhost/java_louis6"'></property>
<property name='"username"' value='"root"'></property>
<property name='"password"' value='"root"'></property>
</bean>
<!-- Hibernate 3 -->
<bean class='"org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"' id='"sessionFactory"'>
<property name='"dataSource"' ref='"dataSource"'></property>
<property name='"annotatedClasses"'>
<list>
<value>com.louis.core.model.Post</value>
<value>com.louis.core.model.Article</value>
</list>
</property>
<property name='"configurationClass"' value='"org.hibernate.cfg.AnnotationConfiguration"'></property>
<property name='"namingStrategy"' ref='"namingStrategy"'></property>
<property name='"packagesToScan"' value='"com.louis.core.model"'></property>
<property name='"hibernateProperties"'>
<props>
<prop key='"hibernate.show_sql"'>true</prop>
<prop key='"hibernate.dialect"'>org.hibernate.dialect.MySQLInnoDBDialect</prop>
<prop key='"hibernate.hbm2ddl.auto"'>update</prop>
</props>
</property>
</bean>
<!-- Transaction management -->
<tx:annotation-driven></tx:annotation-driven>
<bean class='"org.springframework.orm.hibernate3.HibernateTransactionManager"' id='"transactionManager"'>
<property name='"sessionFactory"' ref='"sessionFactory"'></property>
</bean>
<bean class='"org.hibernate.cfg.ImprovedNamingStrategy"' id='"namingStrategy"'></bean>
</context:component-scan></beans>

virtual-config.xml

<?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?>

<beans beans="" context="" http:="" schema="" spring-beans.xsd="" spring-context-3.1.xsd="" spring-tx-3.1.xsd&quot;="" tx="" www.springframework.org="" xmlns='"http://www.springframework.org/schema/beans"' xmlns:context='"http://www.springframework.org/schema/context"' xmlns:tx='"http://www.springframework.org/schema/tx"' xmlns:xsi='"http://www.w3.org/2001/XMLSchema-instance"' xsi:schemalocation='"http://www.springframework.org/schema/beans'>
<tx:annotation-driven></tx:annotation-driven>
<context:annotation-config></context:annotation-config>
<context:component-scan base-package='"com.louis.core"/'>
<!-- DataSource -->
<bean class='"org.springframework.jdbc.datasource.DriverManagerDataSource"' id='"dataSource"'>
<property name='"driverClassName"' value='"org.h2.Driver"'></property>
<property name='"url"' value='"jdbc:h2:mem:test;DB_CLOSE_DELAY=-1"'></property>
<property name='"username"' value='"root"'></property>
<property name='"password"' value='"root"'></property>
</bean>
<!-- Hibernate 3 -->
<bean class='"org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"' id='"sessionFactory"'>
<property name='"dataSource"' ref='"dataSource"'></property>
<property name='"packagesToScan"' value='"scom.louis.core.model.*"/'>
<property name='"annotatedPackages"'>
<list>
<value>com.louis.core.model.Post</value>
<value>com.louis.core.model.Article</value>
</list>
</property>
<property name='"annotatedClasses"'>
<list>
<value>com.louis.core.model.Post</value>
<value>com.louis.core.model.Article</value>
</list>
</property>
<property name='"hibernateProperties"'>
<props>
<prop key='"hibernate.dialect"'> org.hibernate.dialect.H2Dialect</prop>
<prop key='"hibernate.show_sql"'>true</prop>
<prop key='"hibernate.hbm2ddl.auto"'>create</prop>
<prop key='"hibernate.transaction.factory_class"'>org.hibernate.transaction.JDBCTransactionFactory</prop>
</props>
</property>
</property></bean>
<!-- Transaction management -->
<tx:annotation-driven></tx:annotation-driven>
<bean class='"org.springframework.orm.hibernate3.HibernateTransactionManager"' id='"transactionManager"'>
<property name='"sessionFactory"' ref='"sessionFactory"'></property>
</bean>
<bean class='"org.hibernate.cfg.ImprovedNamingStrategy"' id='"namingStrategy"'></bean>
</context:component-scan></beans>

Virtual_PostDaoTest.java

package integration;

import static org.junit.Assert.assertTrue;

import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

import com.louis.core.dao.PostDao;
import com.louis.core.model.Post;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"virtual-config.xml"})
public class Virtual_PostDaoTest {

    @Autowired
    private PostDao postDao;

    @Test
    @Transactional
    public void testDao(){
        Post post1 = new Post();
        post1.setId(null);
        post1.setContent("Some long content");
        post1.setDescription("Some Description");
        post1.setName("Lorem Ipsum");
        post1.setStatus(true);
        post1.setType(1);

        Post post2 = new Post();
        post2.setId(null);
        post2.setContent("Some long content 2");
        post2.setDescription("Some Description 2");
        post2.setName("Lorem Ipsum 2");
        post2.setStatus(true);
        post2.setType(1);

        // save
        postDao.save(post1);
        postDao.save(post2);

        // findById
        Post post1Db = postDao.findById(1L);
        Post post2Db = postDao.findById(2L);

        assertTrue( post1Db.getName() == "Lorem Ipsum" );
        assertTrue( post2Db.getName() == "Lorem Ipsum 2" );

        // findAll
        List

<post> posts = postDao.findAll();

        assertTrue(posts.size() == 2);
    }

}

Beta_PostDaoTest.java

package integration;

import java.util.List;

import static org.junit.Assert.*;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

import com.louis.core.dao.PostDao;
import com.louis.core.model.Post;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"beta-config.xml"})
public class Beta_PostDaoTest {

    @Autowired
    private PostDao postDao;

    @Test
    @Transactional
    public void testFindById(){
        Post post = postDao.findById(2L);
        assertTrue( post != null );
    }

    @Test
    @Transactional
    public void testFindAll(){
        List<post> posts = postDao.findAll();
        assertTrue( posts != null );
    }

}

When I was creating these tests I had to solve 2 problems.

If you get something like this:

org.hibernate.HibernateException: saveOrUpdate is not valid without active transaction

You must remove this statement form your configuration file:

<prop key='"hibernate.current_session_context_class"'>org.hibernate.context.ThreadLocalSessionContext</prop>

If you get something like this:

org.hibernate.exception.SQLGrammarException: could not insert: [com.louis.core.model.Post]
...
Caused by: org.h2.jdbc.JdbcSQLException: Tablela "POST" nie istnieje
....

You must add this DBCLOSEDELAY=-1 statement to url property.

<property name='"url"' value='"jdbc:h2:mem:test;DB_CLOSE_DELAY=-1"'></property>