Unit testing with junit and mockito

If it’s not tested, it’s broken. – Bruce Eckel

I’m a great fan of reliable software. And as a software developer I only want to create software that works reliable. In my opinion crashes in any software (or even worse: data loss) cause distrust from the user. Would you want to run a piece of software that crashes? I wouldn’t. That’s why I think that testing software (and finding crashes before your user does) is a very important part of software development.

So how do we test software? As usual Wikipedia knows lot’s of testing types. You see, there is a large amount of ways to test software. I’ll focus on testing typically done by software developers: unit testing. Unit testing is done, as the name suggests, one a „unit“ of the software. I prefer to use my classes and their methods as my units, others might do differently. So let’s start with a trivial example unit, the SomeDao:

package de.egore911.test;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.Id;

public class SomeDao {
	public static class Some {
		@Id public Integer id;
	}

	@Inject private EntityManager em;

	protected EntityManager getEntityManager() { return em; }

	public Some comeGetSome(Integer id) {
		return getEntityManager().find(Some.class, id);
	}
}

This code is really simple. We have a DAO (data access object) which is able to load entities of the type Some by their ID. The class itself uses CDI to inject the EntityManager instance. This is a very common type of class I’ve seen in lots of web projects, but how to test this unit? At first glance it depends on an injection framework, which needs an entity-manager, which needs a database, which needs dummy data. This is a lot and lot’s of things could cause the test to fail that should not be part of this unit test (e.g. the database was not available). So we need to have a mock object for the EntityManager, which does not actually need to be injected and also does not need a database. This is where mockito comes into play.

import javax.persistence.EntityManager;

import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;

public class SomeDaoTest {

	@Test
	public void testComeGetSome() {
		// Mock the EntityManager to return our dummy element
		Some dummy = new Some();
		EntityManager em = Mockito.mock(EntityManager.class);
		Mockito.when(em.find(Some.class, 1234)).thenReturn(dummy);

		// Mock the SomeDao to use our EntityManager
		SomeDao someDao = Mockito.mock(SomeDao.class);
		Mockito.when(someDao.comeGetSome(1234)).thenCallRealMethod();
		Mockito.when(someDao.getEntityManager()).thenReturn(em);

		// Perform the actual test
		Assert.assertSame(dummy, someDao.comeGetSome(1234));
		Assert.assertNull(someDao.comeGetSome(4321));
	}
}

You can see that this is fairly simple. First you mock an EntityManager that will return a dummy object when the EntityManager.find() method called. Then we make sure our mocked EntityManager is returned when SomeDao.getEntityManager() is called and also the real SomeDao.comeGetSome() is invoked. Of course all this could be done using reflection ourselves, but mockito does all this groundwork for us.

Mockito offers some other nice features, but my primary use is stubbing method calls.

Copyright © christophbrill.de, 2002-2017.