Marc Schwieterman

Simple Stub Creation with Mockito Partial Mocks

When testing code that interacts with lower layers, I often stub out the lower layer to return objects to the code that I’m actually testing. I mostly use stubs generated by a mocking framework, but I occasionally come across cases where the stub needs to do something other than just return a known object. Take the case of a DAO that assigns a generated identifier to a domain object. Here we see a service that takes a name, creates a User object with it, persists the object and returns the generated id to the caller.

1
2
3
4
5
public interface UserService {

  Long create(String name);

}

In this situation, I would want to test that the following are true.

  1. the service calls the persist method on the DAO
  2. the service returns the correct id value

Testing the DAO call is easy enough using a mock.

1
2
3
4
5
6
7
8
9
@Test
public void create_calls_persist() {
  UserDao dao = mock(UserDao.class);
  UserService service = new UserServiceImpl(dao);
  
  service.create("bob kelso");
  
  verify(dao).persist(any(User.class));
}

How do we test that the service returns the correct id? The id will be null by default because it’s a Long. At the very least we should make sure it’s a non-null value, and we would prefer to assert that it’s something specific. We can’t stub the domain object because the service creates it. One option is to create a stub implementation of the DAO that simply sets the object’s id to a known value. Assume that our DAO interface looks like the one below.

1
2
3
4
5
6
7
8
9
public interface UserDao {

  void persist(User user);
  void update(User user);
  void delete(User user);
  User load(Long id);
  User findByName(String name);
  
}

While there aren’t too many methods, we really don’t care about anything but persist, so it’d be nice if we only had to deal with the things we do care about. This is where Mockito comes in. Using the partial mocks feature added in version 1.8.0, we can create an abstract class that only implements the persist method, and let Mockito supply its useful default implementations for the rest of the methods.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class UserServiceTest {
  
  public static final Long ONE_OF_TYPE_LONG = 1L;

  public static abstract class UserDaoStub implements UserDao {

      @Override
      public void persist(User user) {
          user.setId(ONE_OF_TYPE_LONG);
      }

  }

}

We now have an abstract stub for our DAO that will set the id of any objects it persists to a 1 of type Long. You can obviously do something more complicated if needed. Next we use Mockito to provide the rest of the implementation.

1
2
3
4
5
6
7
8
9
10
@Test
public void create_returns_generated_id() {
  UserDao dao = mock(UserDaoStub.class);
  doCallRealMethod().when(dao).persist(any(User.class));
  UserService service = new UserServiceImpl(dao);
  
  Long id = service.create("bob kelso");
  
  assertThat(id, is(ONE_OF_TYPE_LONG));
}

The only thing different about creating a partial mock, is that you need to call either thenCallRealMethod() or doCallRealMethod() to indicate which method calls to delegate to the real object. The example above uses doCallRealMethod() because persist has a void return type. I’ve found this technique to be a very effective way to create focused stubs that allow you to specify what you need to, and not worry about the rest.

Update 2012-05-31

Someone pointed out in the now gone comments that this approach does not work if the stub class needs to carry state. If this is the case for you, you may want to consider a fake. This may also be an opportunity to refactor your code to make it easier to test the desired behavior in isolation.