Tuesday, July 3, 2012

Writing JUnit4 tests - Spring 3.0 Hibernate 3.0 configuration


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.

test-spring-config.xml


  
       
              
       
  

  
       
              
       
       
              
                     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.

3 comments:

  1. Can you please provide other missing source files and make the project complete?

    ReplyDelete
  2. can u upload exjample of struts2 with hibernate junit4 test

    ReplyDelete