Easymock tutorial

Wednesday, 20 April 2011 09:49

Introduction

In unit testing, mock objects can simulate the behavior of complex, real objects and are therefore useful when a real object is impossible to incorporate into your unit test. If an object has any of the following characteristics, it may be useful to use a mock object in its place:

  • supplies non-deterministic results (e.g. the current time or the current temperature);
  • has states that are difficult to create or reproduce (e.g. a network error or database error) or in integration test ;
  • is slow (e.g. a large network resource);
  • does not yet exist (test driven development) or may change behavior;
  • would have to include information and methods exclusively for testing purposes.

In this mock testing tutorial i will use and recommend EasyMock because it's a complete and well documented framework.

Features

Easymock features :

  • Invocation count constraints
  • Recording strict expectations
  • Partial mocking
  • No extra "prepare for test" code
  • No need to use @RunWith annotation or base test class
  • Easier argument matching based on properties of value objects

Requirements

Item version
Easymock 3 version 3.0
Maven version 3.0.3
Junit version 4.8.2
Apache Commons Lang version 2.6
Maven cobertura Plugin version 2.5

Mock Objects

In object-oriented programming, mock objects are simulated objects that mimic the behavior of real objects in controlled ways. A computer programmer typically creates a mock object to test the behavior of some other object, in much the same way that a car designer uses a crash test dummy to simulate the dynamic behavior of a human in vehicle impacts.

Test driven approach

In test driven design, we develop the unit test before the functionality. We write a test that verifies that the class should do X after our call. We prove that the test fails, we then create the component to make the test pass.

Requirement scenario

Let's imagine we are developping a car with a manual transmission. But our car is not a basic car, is a smart car. You are not allowed to change gear if you don't press the clutch otherwise you get a GearBoxException.

User Story

I want a car preventing me to change gear if i don't press the clutch before

Test scenario 1 - Normal scenario

  1. Press the clutch pedal and hold it to the floor
  2. Move the gear shift to first gear
  3. Release the clutch pedal
  4. Press the clutch pedal and hold it to the floor
  5. Move the gear shift to neutral gear
  6. Release the clutch pedal

Test scenario 1 - Exception

  1. Try to move the gear shift to first gear
  2. The gearbox should throw an exception

Objects involved

First of all the Car object. It's the object we want to test. The gearbox object and the clutch are not part of the test. We will explain how to replace them with EasyMock�Mock Objects.

The Gear Box

Gear Box - Easymock tutorial


public class GearBox {
    
    private Gear currentGear = Gear.NEUTRAL;
    
    public void changeUp(){
        currentGear = currentGear.up();
    }

    public void changeDown(){
        currentGear = currentGear.previous();
        
    }
    public Gear getCurrent(){
        return currentGear;
    }

}

Gear enumeration

Gear enumeration defining the gear up and down according to the current state

Spring java source


public enum Gear {
    NEUTRAL(0),
    ONE(1),
    TWO(2),
    THREE(3),
    FOUR(4),
    FIVE(5);
    
    int level;
    
    private Gear(int level){
        this.level = level; 
    }
    
    public Gear down(){
        if (this == NEUTRAL) return NEUTRAL;
        return resolve (this.level-1);
        
    }
    
    public Gear up(){
        if (this == FIVE) return FIVE;
        return resolve (this.level+1);
    }
    
    private Gear resolve (int level){
        for (Gear current : Gear.values()) {
            if (current.level == level) return current;
        }
        return null;
        
    }
}

Abstract Pedal

Abstract pedal object keeping the current state of the pedal

Gear Box - Easymock tutorial


public abstract class AbstractPedal {
    private PedalState state = PedalState.RELEASED;
    
    public void press(){
        state = PedalState.PRESSED;
    }
    public void release(){
        state = PedalState.RELEASED;
    }
    
    public PedalState getState(){
        return state;
    }
}

Pedal state

Gear Box - Easymock tutorial


public enum PedalState {
    PRESSED,
    RELEASED;
}