a peek into my MIND

August 16, 2010

DbUnit and setting up changing data.

Filed under: Java, Testing — Tags: , , , — Bharat Kondeti @ 10:52 pm

DbUnit is used to set up test data for integration tests that rely on a database. One way of importing and exporting database data in DbUnit is by XML data-sets. Assuming we have a table like this…

CUSTOMER
—————————————————————————–
| ID | FirstName | LastName | LicenceExpiryDate |
—————————————————————————–

We are testing a method called isLicenceExpired(id). To unit test this method we can setup some dummy data using DbUnits.

<?xml version='1.0' encoding='UTF-8'?>
<dataset>
  <CUSTOMER ID="1" FIRSTNAME="FirstName1" LASTNAME="LastName1" LICENCEEXPIRTDATE="2010-08-25" 
  <CUSTOMER ID="2" FIRSTNAME="FirstName2" LASTNAME="LastName2" LICENCEEXPIRTDATE="2010-09-15" 
  <CUSTOMER ID="3" FIRSTNAME="FirstName3" LASTNAME="LastName3" LICENCEEXPIRTDATE="2011-01-01" 
</dataset>

Problem with above setup is test-cases would eventually fail because of ‘LicenceExpiryDate’. We need to setup this date such that it’s relative to current date. This is where ReplacementDataSet comes into picture. This class decorates FlatXmlDataSet class to provide replacement functionality. Now we can define your data set as
(more…)

Advertisements

February 4, 2010

Unit testing iBATIS SqlMapClient with EasyMock

Filed under: Java, Testing — Bharat Kondeti @ 3:44 pm

Integrating iBATIS to an application using spring framework is pretty straight forward. Testing a DAO code with live database will make it an integration test.

In general I write two kinds of tests for any DAO code

  • Unit Test – Using EasyMock to mock a DataSource, SqlMapSession and SqlMapClient.
  • Integration test – Using DBUnit to create and delete the db data.

Following is an example DAO code. We are using iBATIS with spring. Code can be much more complex with multiple calls to database and can have some logic inside it.

import java.util.List;

import org.springframework.orm.ibatis.SqlMapClientTemplate;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

public class SomeDAODBImpl extends SqlMapClientDaoSupport {
	
  public List<Customer> lookupCustomers(String zip) {
    List<Customer> customerList = null;
    try {
      SqlMapClientTemplate template = getSqlMapClientTemplate();
      customerList = template.queryForList("Some-Ibatis-Statement-Name", zip);
    } catch (Exception ex) {
       //TODO: Do something with the caught exception
    }
    return customerList;
  }
}

To unit test this code one have to create a mock datasource, session and client. Following is an example unit test code.

(more…)

January 20, 2010

Unit testing multi threaded code with EasyMock

Filed under: Java, Testing — Tags: , , , — Bharat Kondeti @ 4:02 pm

Using java.util.concurrent api, creating asynchronous tasks and executing them in parallel is quite easy.

Following is an example where I create 2 task’s Callable1 and Callable2 and execute them in parallel with Fixed ThreadPoolExecutor. In real world there will be some complex code logic for each of these tasks, and there might also be some logic where these two tasks are executed (callTasksInParallel).

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class MultiThreadExample {
	private static final int threadTimeOut = 10;
	private static final int maxThreadPool = 20;

	private ExecutorService pool = null;

	public MultiThreadExample() {
		pool = Executors.newFixedThreadPool(maxThreadPool);
	}
        
        public void setPool(ExecutorService pool) {
		this.pool = pool;
	}

	public void callTasksInParallel() {
		Future<String> callable1Future = pool.submit(new Callable1());
		Future<String> callable2Future = pool.submit(new Callable2());

		try {
			String response1 = callable1Future.get(threadTimeOut, TimeUnit.SECONDS);
			String response2 = callable2Future.get(threadTimeOut, TimeUnit.SECONDS);

			System.out.println(response1);
			System.out.println(response2);
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		} catch (TimeoutException e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		MultiThreadExample multiThreadExample = new MultiThreadExample();
		multiThreadExample.callTasksInParallel();
	}
}

class Callable1 implements Callable<String> {
	public String call() throws Exception {
		return "I am returned from Callable1";
	}
}

class Callable2 implements Callable<String> {
	public String call() throws Exception {
		return "I am returned from Callable2";
	}
}

Unit testing MultiThreadExample by itself will require mocking of ExecuterService and having Future mocks. Following is an example Junit test code that tests callTasksInParallel as a unit without a dependency for Callable1 and Callable2 classes.

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.easymock.EasyMock;
import org.junit.Before;
import org.junit.Test;

public class MultiThreadExampleTest {
	private ExecutorService executorServiceMock;
	private MultiThreadExample multiThreadExample;

	@Before
	public void setUp() throws Exception {
		executorServiceMock = EasyMock.createMock(ExecutorService.class);
		multiThreadExample = new MultiThreadExample();
		EasyMock.makeThreadSafe(executorServiceMock, true);
	}

	@SuppressWarnings("unchecked")
	@Test
	public void testCallTasksInParallel() throws Exception {
		multiThreadExample.setPool(executorServiceMock);

                //Future mock for Callable1 and set the expectation
		Future<String> callable1Mock = (Future<String>) EasyMock.createMock(Future.class);
		EasyMock.expect(callable1Mock.get(EasyMock.anyLong(), EasyMock.isA(TimeUnit.class))).andReturn("Mock response from callable1");
		EasyMock.replay(callable1Mock);

                //Future mock for Callable2 and set the expectation
		Future<String> callable2Mock = (Future<String>) EasyMock.createMock(Future.class);
		EasyMock.expect(callable2Mock.get(EasyMock.anyLong(), EasyMock.isA(TimeUnit.class))).andReturn("Mock response from callable2");
		EasyMock.replay(callable2Mock);

                //Submit the created futures to the ExecuterService mock and replay them
		EasyMock.expect(executorServiceMock.submit(EasyMock.isA(Callable1.class))).andReturn(callable1Mock);
		EasyMock.expect(executorServiceMock.submit(EasyMock.isA(Callable2.class))).andReturn(callable2Mock);
		EasyMock.replay(executorServiceMock);

		multiThreadExample.callTasksInParallel();
               
		EasyMock.verify(callable1Mock);
		EasyMock.verify(callable2Mock);
		EasyMock.verify(executorServiceMock);
	}
}

Above approach can be used to Unit test all the exception scenarios also.

December 7, 2009

Unit testing Log4j log statements.

Filed under: Java, Testing — Tags: , , — Bharat Kondeti @ 6:15 pm

Logging is an important aspect in writing any software application. Logs properly utilized provide valuable information related to code flow. Mining logs is a way to gather data related to performance of the application and to debug the application.

As part of our current application we wrote tools in Perl and Groovy to mine the logs to collect statistics related to the application. In these tools, we primarily look for string patterns and if some one unintentionally changes the log statements inside the code it breaks our tools also. It’s always beneficial to surround SOME of the log statements with Junit test.

Extending AppenderSkeleton to create a custom append-er.

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.spi.LoggingEvent;

public class TestingAppender extends AppenderSkeleton {

  //We are collecting all the log messages in to a list
  private static List messages = new ArrayList();

  // This method is called when ever any logging happens
  // We are simply taking the log message and adding to our list
  @Override
  protected void append(LoggingEvent event) {
    messages.add(event.getRenderedMessage());
  }

  //This method is called when the appender is closed.
  //Gives an opportunity to clean up resources
  public void close() {
    messages.clear();
  }

  public boolean requiresLayout() {
    return false;
  }

  public static String[] getMessages() {
    return (String[]) messages.toArray(new String[messages.size()]);
  }

  public static void clear() {
    messages.clear();
  }
}

Then we need to write couple of methods to setup the custom append-er and remove it. As part of setUp and tearDown methods of JUnit tests appropriate methods can be called.


private void setupLog4j(TestingAppender appender) {
  //Get the root logger for the
  Logger root = Logger.getRootLogger();

  //If there are no appenders, means Log4j is not initialized properly
  if (!root.getAllAppenders().hasMoreElements()) {
    System.out.println("*******Log4j is not initilized**********");
  } else {

   //Set to appropriate log level and add custom appender
    root.setLevel(Level.ERROR);
    root.addAppender(appender);
  }
}

private void resetLog4j(TestingAppender appender) {
  TestingAppender.clear();
  Logger root = Logger.getRootLogger();
  root.setLevel(Level.FATAL);
  root.removeAppender(appender);
}

As part of tests we can call TestingAppender.getMessages() to get the list of messages and assert for the appropriate log message. This way we can have unit tests for log statements also.

Create a free website or blog at WordPress.com.