a peek into my MIND

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.

Advertisements

1 Comment »

  1. Great article, many thanks !

    Comment by A. Fraisse — December 22, 2014 @ 3:58 pm


RSS feed for comments on this post.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: