Today I started experimenting with dynamic mock objects. I am trying out the http://www.easymock.org library. It is not really hard to start using it. Oke, now tell me what it does.

Easy mock takes an interface and creates an object. Then you configure this object. Tell it what methods will be called and how to respond to these methods. In the end you can verify if everything went like you expected.

Let’s have an example:
First we need an interface

public interface EntryDao {
  public Entry findEntry(int entryId);
  public Collection findLastEntries(int numberOfEntries);
  public void create(Entry entry);
}

Then we need to have a class that uses an implementation of this interface.

public class BlogServiceImpl implements BlogService {
  private EntryDao entryDao;
  public BlogPosting getLastItem() {
    Collection foundEntries = this.entryDao.findLastEntries(1);
    return (BlogPosting) foundEntries.iterator().next();
  }
  public void setEntryDao(EntryDao entryDao) {
    this.entryDao = entryDao;
  }
}

Now we want to test this class, but we do not have an implementation for the EntryDao interface. Thats where EasyMock comes in. We will create a unit test that uses the easymock library to create a mock object for the EntryDao interface, tell it what method calls to expect and what to return. The complete test class looks like this.

public class TestBlogServiceImpl extends TestCase {
  private BlogService blogService;
  private MockControl entryDaoControl;

  private EntryDao entryDao;

  public void setUp() {
  entryDaoControl = MockControl.createControl(EntryDao.class);
    entryDao = (EntryDao)entryDaoControl.getMock();

    BlogServiceImpl blogServiceImpl = new BlogServiceImpl();
    blogServiceImpl.setEntryDao(entryDao);
    this.blogService = blogServiceImpl;
  }

  public void testGetLastItem() {
    entryDao.findLastEntries(1);
    Entry lastEntry = new Entry();
    lastEntry.setEntryId(1);
    Collection foundEntries = new ArrayList();
    foundEntries.add(lastEntry);
    entryDaoControl.setReturnValue(foundEntries);
    entryDaoControl.replay();

    BlogPosting lastPost = blogService.getLastItem();
    assertNotNull(“Last Item should not be null”,lastPost);
    assertEquals(“The obtained last post is not the expected post”,
      lastEntry,lastPost);
    entryDaoControl.verify();
  }
}

Within the setUp method we create the MockControl object and obtain a mock object from the control.

entryDaoControl = MockControl.createControl(EntryDao.class);
entryDao = (EntryDao)entryDaoControl.getMock();

Then in the testGetLastItem method, we start telling the mock object what method calls to expect by really calling them:

entryDao.findLastEntries(1);

After that we tell the mock object the value or object to return when the method is called.

entryDaoControl.setReturnValue(foundEntries);

By calling the replay method we prepare the mock object. Then we start the real test for the method under test and evaluate the returned values.

The final call to the mock controller is the validate method. This checks if the expected calls are made to the mock objects methods.

More information can be found on the easymock website : http://www.easymock.org/Documentation.html

I am working on a sample application with the spring framework. Within the project I am also using easymock, if I encounter problems or nice solutions I will get back on it in this blog.

Mockobjects with easymock