Back to top

vogella training Training Books

Testing with EasyMock - Tutorial

Lars Vogel

Version 1.4

31.01.2013

Revision History
Revision 0.1 06.02.2010 Lars
Vogel
created
Revision 0.2 - 1.4 06.02.2010 - 31.01.2013 Lars
Vogel
bug fixed and enhancements

Testing with EasyMock

This tutorial explains testing with the EasyMock framework within Eclipse. It is based on the EasyMock 3.1 release.


Table of Contents

1. Prerequisites
2. Testing with mock objects
3. Mock frameworks
4. EasyMock
5. Download Easy Mock
6. Tutorial: Using Easy Mock and JUnit
6.1. Create project and classes
6.2. Create tests
7. Thank you
8. Questions and Discussion
9. Links and Literature
9.1. EasyMock

1. Prerequisites

The following tutorial is based on an understanding of unit testing with the JUnit framework.

In case your are not familiar with JUnit please check the following JUnit Tutorial .

2. Testing with mock objects

The process of Unit testing is defined as testing classes or methods in isolation.

Java classes usually depend on other classes. A mock object is a dummy implementation for an interface or a class in which you define the output of certain method calls. Mock objects allow you to unit test the class which should be tested without any dependencies.

You can create these mock objects manually (via code) or use a mock framework to simulate these classes. Mock frameworks allow you to create mock objects at runtime and define their behavior.

The classical example for a mock object is a 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.

These mock objects can be provided to the class which is tested. Therefore the class to be tested should avoid any hard dependency on external data.

Mock frameworks also allow to test the expected interaction with the mock object, e.g. you test which methods have been called on the mock object.

3. Mock frameworks

Popular mock frameworks are EasyMock, jMock and Mockito. The following lists the links to these frameworks.

#jMock
http://jmock.org/

# EasyMock
http://easymock.org/

# Mockito
http://code.google.com/p/mockito/ 

4. EasyMock

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

EasyMock instantiates an object based on an interface or class.

import static org.easymock.EasyMock.createNiceMock;
....

// ICalcMethod is the object which is mocked
ICalcMethod calcMethod = createNiceMock(ICalcMethod.class); 

The createNiceMock() method creates a mock which returns default values for methods which are not overiden. A mock created with the Mock() method will fails in such a case.

EasyMock has several methods which are used to configure the Mock object. The expect() method tells EasyMock to simulate a method with certain arguments. The andReturn() method defines the return value of this method for the specified method parameters. The times() method defines how often the Mock object will be called.

The replay() method is called to make the Mock object available.

// setup the mock object
expect(calcMethod.calc(Position.BOSS)).andReturn(70000.0).times(2);
expect(calcMethod.calc(Position.PROGRAMMER)).andReturn(50000.0);
// Setup is finished need to activate the mock
replay(calcMethod); 

5. Download Easy Mock

Download EasyMock from the EasyMock Homepage and add the easymock.jar library to your classpath.

http://easymock.org/ 

You also need to download the Objenesis and Cglib libraries and add these jars to your classpath.

6. Tutorial: Using Easy Mock and JUnit

6.1. Create project and classes

Create a new Java Project called com.vogella.testing.easymock.first. Create the following classes.

package com.vogella.testing.easymock.first;

public enum Position {
    BOSS, PROGRAMMER, SURFER
} 

package com.vogella.testing.easymock.first;

public interface ICalcMethod {
    double calc(Position position);
} 

package com.vogella.testing.easymock.first;

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 RuntimeException("CalcMethod not yet maintained");
        }
        if (position == null) {
            throw new RuntimeException("Position not yet maintained");
        }
        return calcMethod.calc(position);
    }
} 

The IncomeCalculator class should be tested. The class has the purpose to calculate the salary of a person based on the provided method and position. Obviously the test depends on the provided methods.

6.2. Create tests

Create a new test source folder in your project.

Create a new test for IncomeCalculator and place the new test class in this folder.

package com.vogella.testing.easymock.first.test;

// Use static imports to 
// have direct access to these methods
import static org.easymock.EasyMock.createNiceMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

import org.junit.Before;
import org.junit.Test;

import com.vogella.testing.easymock.first.ICalcMethod;
import com.vogella.testing.easymock.first.IncomeCalculator;
import com.vogella.testing.easymock.first.Position;

public class IncomeCalculatorTest {

  private ICalcMethod calcMethod;
  private IncomeCalculator calc;

  @Before
  public void setUp() throws Exception {
    // NiceMocks return default values for
    // unimplemented methods
    calcMethod = createNiceMock(ICalcMethod.class);
    calc = new IncomeCalculator();
  }

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

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

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

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

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

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

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

} 

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

7. Thank you

Please help me to support this article:

Flattr this

8. 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.com Google Group. I have created a short list how to create good questions which might also help you.

9. Links and Literature

9.1. EasyMock

EasyMock Homepage