Testing with Testng and EasyMock

I had my brush with testng and easymock some time back. It’s quite cutting edge technology and works with java 5 and above only since it relies heavily on some java 5 features such as annotations and the assert keyword.
I shall be describing a slightly unusual scenario in this post.
EasyMock works with interfaces and requires that all your classes implement an interface. However there is an extension of EasyMock available that works with classes as well.

Here are some useful links for testng and easymock before you attempt something serious:

http://testng.org/doc/documentation-main.html
http://easymock.org/EasyMock2_2_Documentation.html

You need to downlaod the testng and easymock jars and have them on your classpath before you run this example. The following link describes how you can plugin testng to your eclipse installation:

http://testng.org/doc/eclipse.html

Here are the classes I used:

Bean.java

class Bean implements IBean {
	private int i;

	public Bean(int i) {
		this.i = i;
	}

	public int getBeanId() {
		return i;
	}
};

IBean.java

public interface IBean {
	public int getBeanId();
}

BeanInspectorFactory.java

class BeanInspectorFactory implements IBeanInspectorFactory {
	public BeanInspector getBeanInspectorInstance() {
		return new BeanInspector();
	}
};

IBeanInspectorFactory.java

public interface IBeanInspectorFactory {

	public IBeanInspector getBeanInspectorInstance();
}

BeanInspector.java

class BeanInspector implements IBeanInspector {
    public void inspect(IBean bean) {
        System.out.println("Bean " + bean.getBeanId()
                + " successfully inspected");
    }
};

IBeanInspector.java

public interface IBeanInspector {
	public void inspect(IBean bean);
}

InspectorThread.java – The class to test

public class InspectorThread implements Runnable {
	private IBeanInspectorFactory beanInspectorFactory;

	private IBeanInspector beanInspector;

	private IBean bean;

	public InspectorThread(IBeanInspectorFactory beanInspectorFactory,
			IBean bean) {
		this.beanInspectorFactory = beanInspectorFactory;
		this.bean = bean;
	}

	public void run() {
		beanInspector = beanInspectorFactory.getBeanInspectorInstance();
		beanInspector.inspect(bean);
	}
};

InspectorThreadInvoker.java

public class InspectorThreadInvoker {
	public static void main(String[] args) {
		Bean bean = new Bean(1);
		BeanInspectorFactory beanInspectorFactory = new BeanInspectorFactory();
		InspectorThread t = new InspectorThread(beanInspectorFactory, bean);
		Thread thread = new Thread(t);
		thread.start();
	}
}

BeanInspectorTest.java – The test class uses testng and easymock

import org.easymock.EasyMock;
import org.easymock.IMocksControl;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import static org.easymock.EasyMock.*;

public class BeanInspectorTest {
	IMocksControl mockControl;

	/**
	 * Create Mock Control before the tests.
	 */
	@BeforeClass
	public void setUp() {
		mockControl = (IMocksControl) EasyMock.createStrictControl();
	}

	/**
	 * Reset the Mock Control after each test.
	 */
	@AfterTest
	public void cleanUp() {
		mockControl.reset();
	}

	@Test
	public void testInspection() {
		IBeanInspectorFactory mockbeanInspFact = mockControl
				.createMock(IBeanInspectorFactory.class);
		IBeanInspector mockBeanInspector = mockControl
				.createMock(IBeanInspector.class);
		IBean mockbean = mockControl.createMock(IBean.class);
		expect(mockbeanInspFact.getBeanInspectorInstance()).andReturn(
				mockBeanInspector);
		mockBeanInspector.inspect(mockbean);
		mockControl.replay();
		InspectorThread t = new InspectorThread(mockbeanInspFact, mockbean);
		Thread thread = new Thread(t);
		thread.start();
		mockControl.verify();
	}
}

You also need an xml file for configuration but it need not be named testng.xml as I have done:

testng.xml


 

    
        
            
        
    

The test runs successfully and prints out:

[Parser] Running:
D:workprojectsGreatMockGreatMocktestng.xml


===============================================
Suite1
Total tests run: 1, Failures: 0, Skips: 0
===============================================


Testng expects the lines between mockControl.replay(); and mockControl.verify(); to emulate the mock actions before mockControl.replay();

For example if I modified the test method with a minor change in the call sequence .. viz.

@Test
	public void testInspection() {
		IBeanInspectorFactory mockbeanInspFact = mockControl
				.createMock(IBeanInspectorFactory.class);
		IBeanInspector mockBeanInspector = mockControl
				.createMock(IBeanInspector.class);
		IBean mockbean = mockControl.createMock(IBean.class);
		mockBeanInspector.inspect(mockbean);
		expect(mockbeanInspFact.getBeanInspectorInstance()).andReturn(
				mockBeanInspector);
		// mockBeanInspector.inspect(mockbean);
		mockControl.replay();
		InspectorThread t = new InspectorThread(mockbeanInspFact, mockbean);
		Thread thread = new Thread(t);
		thread.start();
		mockControl.verify();
	}

I get the following error: (Note I have made the call to inspect() before it is actually done in the actual code.)

[Parser] Running:
D:\work\projects\GreatMock\GreatMock\testng.xml
Exception in thread "Thread-0" java.lang.AssertionError:
Unexpected method call getBeanInspectorInstance():
inspect(EasyMock for interface IBean): expected: 1, actual: 0
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:32)
at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:61)
at $Proxy6.getBeanInspectorInstance(Unknown Source)
at InspectorThread.run(InspectorThread.java:15)
at java.lang.Thread.run(Unknown Source)
===============================================
Suite1
Total tests run: 1, Failures: 1, Skips: 0
===============================================

The application can be downloaded here

About cuppajavamattiz
Matty Jacob - Avid technical blogger with interests in J2EE, Web Application Servers, Web frameworks, Open source libraries, Relational Databases, Web Services, Source control repositories, ETL, IDE Tools and related technologies.

Comments are closed.

%d bloggers like this: