Testing with EasyMock - Tutorial

上一篇 / 下一篇  2011-02-14 16:53:45 / 个人分类:E文教程

Lars Vogel

Version 0.1   Copyright © 2010 Lars Vogel   06.02.2010

Revision History
Revision 0.106.02.2010Lars Vogel
separated from JUnit article http://www.vogella.de/articles/JUnit/article.html

Testing with EasyMock

This article explains testing with the Easymock framework within Eclipse.


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 can be provided to the class which should be tested to avoid any 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.

3. Thank you2. Using Easy Mock and Junit

Download EasyMock from the Easy Homepage and add the easymock.jar 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.

Please help me maintaining this article:
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 JM
X

TAG:

 

评分:0

我来说两句

Open Toolbar