by Lars Vogel

Follow me on twitter

Lars Vogel on Google+

Testing with EasyMock - Tutorial

Lars Vogel

Version 0.4

14.06.2011

Revision History
Revision 0.1 06.02.2010 Lars
Vogel
created
Revision 0.2 - 0.4 06.02.2010 - 14.06.2011 Lars
Vogel
bug fixed and enhancements

Testing with EasyMock

This article explains testing with the EasyMock framework within Eclipse. It is based on EasyMock 3.0 but should also work on later versions.


Table of Contents

1. EasyMock and Mock Objects Overview
1.1. Testing and Mock Objects
1.2. EasyMock
2. Using Easy Mock and Junit
3. Thank you
4. Questions and Discussion
5. Links and Literature
5.1. Performance

1. EasyMock and Mock Objects Overview

The following is based on an understanding JUnit. In case your are not familiar with JUnit please check the following JUnit Tutorial .

1.1. Testing and Mock Objects

Unit testing is defined as testing classes or methods in isolation. Java classes usually depend on other classes. A mock object is a dummy interface or class in which you define the dummy output of a certain method call. These objects should be provided to the class which is tested. Therefore the class to be tested should to avoid any hard dependency to external data. The classical example is a mock object for a data provider. In production a real database is used but for testing a mock object simulates the database and ensures that the test conditions are always the same.

To unit test your class you need to simulate /control the other classes. The best way is to provide mocks to the class which should be tested. The can either program these classes manually or use a mock framework to simulate these classes.

1.2. EasyMock

EasyMock is a popular mock framework which can be easily used in conjunction with JUnit. The following demonstrates the usage of EasyMock.

2. Using Easy Mock and Junit

Download EasyMock from the EasyMock Homepage and add the easymock.jar to your classpath. You also need to download Objenesis and Cglib and add there jars to your classpath.

Create a new Java Project JavaMockTest. Create the following classes. The class IncomeCalculator should be tested. The class has the purpose to calculate based on the provided method and position the salary of a person. Obviously the test depends on the provided methods.

			
package income;

public enum Position {
	BOSS, PROGRAMMER, SURFER
}

		

			
package income.exceptions;

public class PositionException extends RuntimeException {

	private static final long serialVersionUID = 1L;

	public PositionException(String message) {
		super(message);
	}
}

		

			
package income.exceptions;

public class CalcMethodException extends RuntimeException {

	private static final long serialVersionUID = 1L;

	public CalcMethodException(String message) {
		super(message);
	}
}

		

			
package income.method;

import income.Position;

public interface ICalcMethod {

	public abstract double calc(Position position);

}
		

			
package income;

import income.exceptions.CalcMethodException;
import income.exceptions.PositionException;
import income.method.ICalcMethod;


public class IncomeCalculator{
	
	private ICalcMethod calcMethod;
	private Position position;

	public void setCalcMethod(ICalcMethod calcMethod){
		this.calcMethod = calcMethod;
	}
	public void setPosition(Position position){
		this.position = position;
	}
	public double calc (){
		if (calcMethod==null){
			throw new CalcMethodException("CalcMethod not yet maintained");
		}
		if (position==null){
			throw new PositionException("Position not yet maintained");
		}
		return calcMethod.calc(position);
	}
}

		

Using Eclipse JUnit functionality create a new test for IncomeCalulator. In my example I did also create a new source folder "test" before in which I place the test classes.

Here is the test using EasyMock.

			
package income;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import income.exceptions.CalcMethodException;
import income.exceptions.PositionException;
import income.method.ICalcMethod;

import org.easymock.EasyMock;
import org.junit.Before;
import org.junit.Test;

public class IncomeCalculatorTest {

	private ICalcMethod calcMethod;
	private IncomeCalculator calc;

	@Before
	public void setUp() throws Exception {
		calcMethod = EasyMock.createMock(ICalcMethod.class);
		calc = new IncomeCalculator();
	}

	@Test
	public void testCalc1() {
		// Setting up the expected value of the method call calc
		EasyMock.expect(calcMethod.calc(Position.BOSS)).andReturn(70000.0)
				.times(2);
		EasyMock.expect(calcMethod.calc(Position.PROGRAMMER))
				.andReturn(50000.0);
		// Setup is finished need to activate the mock
		EasyMock.replay(calcMethod);

		calc.setCalcMethod(calcMethod);
		try {
			calc.calc();
			fail("Exception did not occur");
		} catch (PositionException e) {

		}
		calc.setPosition(Position.BOSS);
		assertEquals(70000.0, calc.calc());
		assertEquals(70000.0, calc.calc());
		calc.setPosition(Position.PROGRAMMER);
		assertEquals(50000.0, calc.calc());
		calc.setPosition(Position.SURFER);
		EasyMock.verify(calcMethod);
	}

	@Test(expected = CalcMethodException.class)
	public void testNoCalc() {
		calc.setPosition(Position.SURFER);
		calc.calc();
	}

	@Test(expected = PositionException.class)
	public void testNoPosition() {
		EasyMock.expect(calcMethod.calc(Position.BOSS)).andReturn(70000.0);
		EasyMock.replay(calcMethod);
		calc.setCalcMethod(calcMethod);
		calc.calc();
	}

	@Test(expected = PositionException.class)
	public void testCalc2() {
		// Setting up the expected value of the method call calc
		EasyMock.expect(calcMethod.calc(Position.SURFER)).andThrow(
				new PositionException("Don't know this guy")).times(1);

		// Setup is finished need to activate the mock
		EasyMock.replay(calcMethod);
		calc.setPosition(Position.SURFER);
		calc.setCalcMethod(calcMethod);
		calc.calc();
	}

}

		

The expect method tells easy mock to expect a certain method with certain arguments. andReturn defines the return value of this method. The method times defines how often the Mock object will be called.

The reply method needs to be called to make the Mock object available.

After execution of the test you can call the method verify to check if the Mock Object was called as defined.

3. Thank you

Please help me to support this article:

Flattr this

4. Questions and Discussion

Before posting questions, please see the vogella FAQ. If you have questions or find an error in this article please use the www.vogella.de Google Group. I have created a short list how to create good questions which might also help you.

5. Links and Literature

5.1. Performance

https://www.ibm.com/developerworks/java/library/j-jtp09196/ Java theory and practice: Instrumenting applications with JMX