I have modified the earlier example to show you how we
can write the JUnit4 test case for the same Dao class configured on Spring 3.0
environment.
Technologies used:
Java 6
JUnit4
Spring 3.0
Hibernate 3.0
Maven 3.0
UserDao has one method to insert a User entity to the
USERS table – addUser().
UserDao.java
package com.ceyloncuisine.dao; import com.ceyloncuisine.domain.User; public interface UserDao { public void addUser(User user); }
To keep this simple, only the interface method is shown.
When writing the test case, it’s always good to have a
base test class which we can store all the common methods and utility methods.
BaseTest.java
package com.ceyloncuisine.base; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.junit.Ignore; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests; import org.springframework.test.context.transaction.TransactionConfiguration; @Ignore @ContextConfiguration(locations = "/test-spring-config.xml") @TransactionConfiguration(transactionManager = "txManager", defaultRollback = true) public class BaseTest extends AbstractTransactionalJUnit4SpringContextTests { @Autowired SessionFactory sessionFactory; protected void flush() { this.sessionFactory.getCurrentSession().flush(); } protected Session getCurrentSession() { return sessionFactory.getCurrentSession(); } }
We need to extend AbstractTransactionalJUnit4SpringContextTests.
Use of annotations will make things easier for you.
@Ignore – I don’t need this class to run as a test case,
this is only used as a base class. So @Ignore annotation will make sure this
will be ignored at test run.
@ContextConfiguration – This is how to load the
application context for tests. We need to have a separate Spring
configuration that will be used for tests. You have to place this
configuration file in src\test\resources folder. I will include the test
configuration file later in this article.
@TransactionConfiguration – We need to provide
transactional support for testing. This is where to specify the transaction
manager we’ll be using.
By default the transaction manager name is called
“transactionManager”, if you have some other name for your transaction manager,
as in this example, you have to specify the name. “txManager” is defined in the
‘test-spring-config.xml’ file.
‘sessionFactory’ is configured in the
test-spring-config.xml file.
Now let’s see the test class.
UserDaoTest.java
package com.ceyloncuisine.dao; import junit.framework.Assert; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import com.ceyloncuisine.base.BaseTest; import com.ceyloncuisine.domain.User; public class UserDaoTest extends BaseTest { @Autowired UserDao userDao; @Test public void testAddUser() { long count = -1; String testFname = "bob"; // HQL query to get the count. String query = "select count(u.fname) " + "from User u where u.fname = ?"; // Get the count before the Dao method call. count = (Long) getCurrentSession().createQuery(query) .setString(0, testFname).uniqueResult(); // There should be no existing record with the name specified. Assert.assertEquals("A user already exists in the DB", 0, count); // Call the Dao method to add new user. User user = new User(); user.setFname(testFname); userDao.addUser(user); // flush the session so we can get the updated record. flush(); // Get the count after the Dao method call. count = (Long) getCurrentSession().createQuery(query) .setString(0, testFname).uniqueResult(); // A record should be fetched matching the specified name. Assert.assertEquals("User was not found in the DB", 1, count); } }
The method
uniqueResult()is used as the query returns a
single object. If the query is returns a list of objects we should use list() method instead.
The @TransactionConfiguration setting in the base test
class has an attribute ‘defaultRollback’. The value of this is ‘true’ by
default, meaning the transaction will be rolled back at the end. If you set
this to ‘false’, test data inserted to the database will not be removed.
TransactionConfiguration(transactionManager =
"txManager", defaultRollback=false)
Therefore the inserted record will be removed from the
database when the test case completes and the database remains clean so you
don’t have to bother about cleaning test data.
This is the Spring configuration file used for tests.
com/ceyloncuisine/hibernate/User.hbm.xml org.hibernate.hql.classic.ClassicQueryTranslatorFactory org.hibernate.dialect.MySQLDialect
test-spring-config.xml
defines the sessionFactory
and the dataSource
beans required to communicate with the MySQL database. sessionFactory
defines the hibernate mapping file for the User entity. (User.hbm.xml)
A HibernateTransactionManager is used to handle
transactions and it is defined as “txManager”.
Below is the pom.xml file used to configure dependencies
with Maven.
4.0.0 CeylonCuisine CeylonCuisine 0.0.1-SNAPSHOT war CeylonCuisine Java.Net http://download.java.net/maven/2/ com.springsource.repository.bundles.release SpringSource Enterprise Bundle Repository - SpringSource Bundle Releases http://repository.springsource.com/maven/bundles/release com.springsource.repository.bundles.external SpringSource Enterprise Bundle Repository - External Bundle Releases http://repository.springsource.com/maven/bundles/external org.springframework org.springframework.core 3.1.1.RELEASE org.springframework org.springframework.beans 3.1.1.RELEASE org.springframework org.springframework.transaction 3.1.1.RELEASE org.springframework org.springframework.test 3.1.1.RELEASE org.springframework spring-hibernate3 2.0.8 junit junit 4.10 mysql mysql-connector-java 5.1.9 org.hibernate hibernate 3.2.7.ga dom4j dom4j 1.6.1 commons-collections commons-collections 3.2.1 cglib cglib 2.2 antlr antlr 2.7.7 asm asm 3.3.1
So, that’s it. Hope this post will help you to configure
your JUnit4 test cases.
Can you please provide other missing source files and make the project complete?
ReplyDeletethanks a lot for this :)
ReplyDeletecan u upload exjample of struts2 with hibernate junit4 test
ReplyDelete