EasyMock in 5 minutes

A couple of months ago I started in a new project at IBM. That new project is a big challenge in my life, certainly it is the biggest project I have already worked.
As any new project, there are new tools, APIs, frameworks, that we need to learn. In that project for example, I had to learn the newest EasyMock. Actually, I’ve already used EasyMock a long time ago (maybe in 2005), but in the last years, I was using JMock instead.
Fortunately, the EasyMock 2.4 is similar than JMock, and because of this I had no trouble to learn it.
In this short topic, I’m going to show up how to get started with EasyMock 2.4. This topic doesn’t intend to be a tutorial, only an example of how the EasyMock is simple and can help us in the mockering.
Before get started, make sure that you hava Java 1.5 or higher installed and JUnit 4 (JUnit 3 is also supported, but I really like the annotations features
).
Downloading EasyMock
Basically you have to choices: Use a build tool (like Maven) to manage the JARs dependencies or to to the EasyMock’s official website: http://www.easymock.org/ and download its latest version (2.4). Probably you’re gonna download a file called easymock2.4.zip. Extract that file and a easymock2.4 folder will be created. There are documentation, javadoc and samples within the directory, but you will use only the easymock.jar file.
Creating the project
I’m going to use Maven and M2Eclipse plugin to create that project into Eclipse, but you’re free to use another IDE. You can check a Maven example here.
Besides create the project,also add the junit-4.5.jar and easymock.jar file into classpath. If you’re using Maven, add the junit-4.5 and easymock dependencies. The pom looks like below:
<project> <modelVersion>4.0.0</modelVersion> <groupId>EasyMockExample</groupId> <artifactId>EasyMockExample</artifactId> <packaging>jar</packaging> <version>0.0.1-SNAPSHOT</version> <name>EasyMockExample</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.5</version> <scope>test</scope> </dependency> <dependency> <groupId>org.easymock</groupId> <artifactId>easymock</artifactId> <version>2.4</version> </dependency> </dependencies> </project>
Creating the Interfaces and Classes
Let’s use a common example that happens in the projects that use EJB2 and remote call. We have a service layer, that will look up for some values from Repository (DAO). That Repository will return the Entity and the Service must copy only the required values to the TO (Transfer Object).
We’re going to test the Service layer, hence, we must MOCK the Repository.
Note: Use the approach (BO and VO) only if you are using EJB2 (CMP entities) with remote call. This post is merely an example.
All the interfaces and classes could look like below:
Customer Entity
package com.jairrillo.easymockexample.entities; public class Customer { private Integer id; private String name; private String phoneNumber; //Getters and Setters
Note: Supposing that is a CMP entity (not serializable). Hence, we cannot send it through the remote call (it must be serializable to do that)
CustomerTO : Transfer Object
package com.jairrillo.easymockexample.transferobjects; import java.io.Serializable; public class CustomerTO implements Serializable { private static final long serialVersionUID = 1L; private String name; public CustomerTO() { } public CustomerTO(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
Note: That is a Serializable Object. We only copy the required values. In that case, only the Customer’s name is required.
CustomerRepository (DAO)
package com.jairrillo.easymockexample.repositories; import java.util.List; import com.jairrillo.easymockexample.entities.Customer; public interface CustomerRepository { public List<Customer> getListOfPendingCustomers(); }
CustomerService (Business Object layer)
package com.jairrillo.easymockexample.services; import java.util.List; import com.jairrillo.easymockexample.repositories.CustomerRepository; import com.jairrillo.easymockexample.transferobjects.CustomerTO; public interface CustomerService { public List<CustomerTO> getListOfPendingCustomers(); public void setRepository(CustomerRepository repository); }
As you can see above, we have two interfaces (CustomerRepository and CustomerService) and two concrete classes (Customer and CustomerVO). Also, we need a new concrete class to implement the CustomerService. The class looks like (no implementation yet).
package com.jairrillo.easymockexample.services; import java.util.List; import com.jairrillo.easymockexample.repositories.CustomerRepository; import com.jairrillo.easymockexample.transferobjects.CustomerTO; public class CustomerServiceImpl implements CustomerService { private CustomerRepository repository; public List<CustomerTO> getListOfPendingCustomers() { // TODO Auto-generated method stub return null; } /** * Inject the Repository through that method. * We can use Spring, EJB or even Google Guice to do that. * * @param repository */ public void setRepository(CustomerRepository repository) { this.repository = repository; } }
Creating the Test Case
We’re going to test the CustomerServiceImpl class and mock the CustomerRepository interface.
If you’re using Maven, you can create the test case into src/test/java directory. If not, create a test directory in the same level than src. Below, following our test case.
package com.jairrillo.easymockexample.services; import static org.easymock.EasyMock.*; import java.util.ArrayList; import java.util.List; import static junit.framework.Assert.*; import org.junit.Before; import org.junit.Test; import com.jairrillo.easymockexample.entities.Customer; import com.jairrillo.easymockexample.repositories.CustomerRepository; import com.jairrillo.easymockexample.transferobjects.CustomerTO; public class CustomerServiceImplTest { /** * Class underTest */ private CustomerService customerService; /** * Mock object */ private CustomerRepository mock; @Before public void setUp() throws Exception { //Starting the class underTest this.customerService = new CustomerServiceImpl(); //Starting mock object this.mock = createStrictMock(CustomerRepository.class); } /** * This method test the getListOfPendingCustomers when none value is returned from * Repository * In that case, the method must return an Empty {@link java.util.List} */ @Test public void testGetListOfPendingCustomersWhenNoneCustomerIsRetrieved() { //Adding behavior for that method expect(this.mock.getListOfPendingCustomers()).andReturn(new ArrayList<Customer>()); replay(this.mock); //Injecting Repository into CustomerService this.customerService.setRepository(this.mock); //Testing the return assertEquals(true, this.customerService.getListOfPendingCustomers().isEmpty()); } /** * This method test the getListOfPendingCustomers when only ONE value is returned from the Repository */ @Test public void testGetListOfPendingCustomersWhenOneCustomerIsRetrieved() { List<Customer> listCustomers = new ArrayList<Customer>(); Customer customer = new Customer(); customer.setId(1); customer.setName("Jair Rillo Junior"); customer.setPhoneNumber("123456789"); listCustomers.add(customer); //Adding behavior for that method expect(this.mock.getListOfPendingCustomers()).andReturn(listCustomers); replay(this.mock); //Injecting Repository into CustomerService this.customerService.setRepository(this.mock); //Testing the return List<CustomerTO> listCustomersTO = this.customerService.getListOfPendingCustomers(); assertEquals(false, listCustomersTO.isEmpty()); assertEquals(1, listCustomersTO.size()); //Testing the returned value CustomerTO customerTO = listCustomersTO.get(0); assertEquals("Jair Rillo Junior", customerTO.getName()); } }
As you can see above, EasyMock is really simple to use. Like other mock object, we must start it, add the behavior and test it.
Running the Test Case
Right click on Test Case class, go to Run As -> JUnit. You’re gonna get a RED BAR. It means the test failed, but why? Because our implementation class isn’t implement yet (duh). Let’s do that now.
Implementing The CustomerServiceImpl
The CustomerServiceImpl implemented looks like below:
package com.jairrillo.easymockexample.services; import java.util.ArrayList; import java.util.List; import com.jairrillo.easymockexample.entities.Customer; import com.jairrillo.easymockexample.repositories.CustomerRepository; import com.jairrillo.easymockexample.transferobjects.CustomerTO; public class CustomerServiceImpl implements CustomerService { private CustomerRepository repository; public List<CustomerTO> getListOfPendingCustomers() { //List that will be returned List<CustomerTO> listCustomerTO = new ArrayList<CustomerTO>(); //Retrieving values from Repository List<Customer> listCustomers = repository.getListOfPendingCustomers(); //Copying (only required) values to TO for (Customer customer : listCustomers) { //Only NAME is required for that requirement CustomerTO customerTO = new CustomerTO(customer.getName()); //adding the CustomerTO to list listCustomerTO.add(customerTO); } return listCustomerTO; } /** * Inject the Repository through that method. * We can use Spring, EJB or even Google Guice to do that. * * @param repository */ public void setRepository(CustomerRepository repository) { this.repository = repository; } }
Supposing our entity has many attributes, as well as many objects related, however we want only send up the NAME (In a remote call, you can use a TO to transfer objects over the network when the entity is not serializable).
Running the Test Case again
Run again the test case and in this time you should get the GREEN BAR!!

Conclusion
With this topic, you can have an idea of how the EasyMock works. Of course it has others features, but it can be a starting point. In a real software, you should create more than only two test method, but I leave this homework for you.
I hope this topic be useful for anyone. If you have any question or comment, fell free to leave a message below.
You can download the example below here.


Brazilian guy, IT Specialist, Linux User, IBM Certified SOA Fundamentals, Rational Developer, Sun Certified Java Associate 1.0, Sun Certified Java Programmer 1.4, Sun Certified Web Component Developer 1.4 and Sun Certified Business Component Developer 5. Also Ruby and Python enthusiastic.
great tutorial