Friday 10 July 2009

EasyMock - Reason to update to the latest version

I have recently started working on a new project that consisted of three dependant Java projects.

These three projects were using two different versions of EasyMock so first off I decided to bring them into line. The projects are all Java5 but one project had EasyMock 2.4 and the other two had EasyMock 1.3

Following on from Andrew Beacock's article on using easy mock's class extensions I decided to give that a go.

Strangely after upgrading some of the tests were failing. Why ?

Well it looks to me like a bug in the old version of EasyMock 1.3,
so the easy answer is upgrade. The bug appears to be that you can not call MockControl.expectAndDefaultReturn() more than once.

Here is the test using the old code, and below that a test class using 2.4.

EasyMock 1.3 version:
package uk.co.utilisoft.entrecaweb.web.validators;

import java.util.ArrayList;
import java.util.List;

import junit.framework.TestCase;

import org.easymock.MockControl;

public class TryOldEasyMock extends TestCase{

public void testSingleCall(){
List<String> list = new ArrayList<String>();
list.add("hello");
MockControl control = MockControl.createControl(TestMock1.class);
TestMock1 mock = (TestMock1)control.getMock();

ClassUnderTest1 classUnderTest = new ClassUnderTest1();
classUnderTest.setService(mock);

control.expectAndDefaultReturn(mock.getLength("hello"), 5);
control.replay();
assertEquals(5, classUnderTest.getLength(list));
control.verify();
}


public void testTwoCalls(){
List<String> list = new ArrayList<String>();
list.add("hello");
list.add("bye");

MockControl control = MockControl.createControl(TestMock1.class);
TestMock1 mock = (TestMock1)control.getMock();

ClassUnderTest1 classUnderTest = new ClassUnderTest1();
classUnderTest.setService(mock);

control.expectAndDefaultReturn(mock.getLength("hello"), 5);
control.expectAndDefaultReturn(mock.getLength("bye"), 95);
control.replay();


assertEquals("this is the wrong value & should fail.", 190, classUnderTest.getLength(list));
assertEquals("this is the correct value & should pass.", 100, classUnderTest.getLength(list));
control.verify();
}
}

class ClassUnderTest1{
private TestMock1 service;

public void setService(TestMock1 service) {
this.service = service;
}

public int getLength(List<String> someText)
{
int total = 0;
for (String value : someText) {
total += service.getLength(value);
}
return total;
}

}

interface TestMock1
{
public int getLength(String someText);
}


EasyMock 2.4 version, using the class extensions jar:
package uk.co.utilisoft.entrecaweb.web.validators;

import java.util.ArrayList;
import java.util.List;

import junit.framework.TestCase;
import static org.easymock.classextension.EasyMock.*;

public class TryEasyMockTest extends TestCase {

public void testSingleCall()
{
List<String> list = new ArrayList<String>();
list.add("hello");

TestMock mock = createMock(TestMock.class);

expect(mock.getLength("hello")).andReturn(5);

ClassUnderTest classUnderTest = new ClassUnderTest();
classUnderTest.setService(mock);
replay(mock);

assertEquals(5, classUnderTest.getLength(list));
verify(mock);
}

public void testTwoCalls()
{
List<String> list = new ArrayList<String>();
list.add("hello");
list.add("bye");

TestMock mock = createMock(TestMock.class);

expect(mock.getLength("hello")).andReturn(5);
expect(mock.getLength("bye")).andReturn(95);

ClassUnderTest classUnderTest = new ClassUnderTest();
classUnderTest.setService(mock);
replay(mock);

assertEquals(100, classUnderTest.getLength(list));
verify(mock);
}
}

class ClassUnderTest{
private TestMock service;

public void setService(TestMock service) {
this.service = service;
}

public int getLength(List<String> someText)
{
int total = 0;
for (String value : someText) {
total += service.getLength(value);
}
return total;
}

}

class TestMock
{
public int getLength(String someText){
return someText.length();
}
}

No comments: