Next page | Contents page |

Using mock objects fully

Using a mock object in JUnit tests usually involves several steps:

  1. Create the mock, using method createMock(class-literal)
  2. Record the method calls that the object should expect to receive and, optionally, cause things to happen on some of them (eg, return a particular value or throw a particular type of exception)
  3. Rewind the recording, by calling replay(mockObject)
  4. Do the tests (JUnit assertions etc) that will cause the recorded method calls.
  5. Check that expected method calls did occur: verify(mockObject)

Creating mock objects

There are really 3 methods for creating mock objects. Eg,

Recording expectations

Another static method of EasyMock is expect(). Used in recording. Eg,

expect(mockPerson.getAgeInYears());

NB: Methods with void return are simply coded, without expect().

If the same call occurs many times (eg, 8) we can follow it with

expectLastCall().times(8); // or
expectLastCall().times(3, 10); // Min 3, max 10 times or
expectLastCall().anyTimes();

The call can be forced to return a particular value (base type or object reference):

expect(mockPerson.getAgeInYears()).andReturn(20);

or to throw any java.lang.Throwable:

expect(mock.xyz()).andThrow(new CantDoThatException());

replay () & verify ()

Don't forget to rewind the mock objects between recording expectations and running the tests. Use

public static void EasyMock.replay (Object... mocks)

NB: Do not confuse with reset(Object... mocks) which is for enabling a different set of expectations to be recorded on existing mocks. Since we recreate our mocks for each test by using @Before, we are unlikely to use reset()

Also remember to check after the tests that the expected method calls did occur, by using

public static void EasyMock.verify (Object... mocks)

An EasyMock example

Suppose class Group has a list of Person objects and methods such as void addPerson(Person p) and List <String> getNames(). We might test the latter method in GroupTest with

private Group g;            // Object to unit test
private Person mockPerson1; // In another unit, no test here

@Before 
public void setUp ()
{
	mockPerson1 = createMock (Person.class);
	g = new Group ();
	g.addPerson (mockPerson1); 
}

@Test 
public void testGetNames ()
{
	expect (mockPerson1.getName ()).andReturn ("Ann"); // RECORD
	replay (mockPerson1);                                        // REWIND
	assertEquals ("Ann", g.getNames ().get (0));       // TEST
	verify (mockPerson1);                                        // CHECK
}

In this example it is important to realise that getNames() must involve getName() on each Person in the list inside g.

Next page | Contents page |