Spring 3 @Autowired Unit Tests with Mockito

I’ve been wanting to enhance the unit tests I have in my application for awhile. I’m using Spring 3 testing facilities, but most of my tests are “integration” tests. I finally carved out a bit of time to enable better unit tests in my application. This is an example of a unit test of a simple service class using Spring 3 annotations. I am using Mockito to mock the dependencies.

First my service class. Like I said, simple. Just two methods and straightforward logic.

package my.app.service;

import java.util.List;

import my.app.dao.SupervisorDAO;
import my.app.model.Supervisor;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class SupervisorService {

	@Autowired private SupervisorDAO supervisorDao;

	@Transactional(readOnly=true)
	public List getSupervisors() {
		return supervisorDao.getSupervisors();
	}

	/**
	 * Determine if the supervisor is responsible for any users for the
	 * specified department
	 * @param dbId The dbId of the supervisor
	 * @param department The department to look for
	 * @return true if there are users assigned to the superivsor for the department
	 */
	public boolean isSupervisorResponsibleForUser(int dbId, String department) {
		if (dbId == 0) {
			throw new IllegalArgumentException("A dbId is required");
		}
		if (department == null) {
			throw new IllegalArgumentException("department is required");
		}
		boolean hasUsers = false;
		int numAssignedUsers = supervisorDao.getUserCountForSupervisor(dbId, department);
		if (numAssignedUsers > 0) {
			hasUsers = true;
		}
		return hasUsers;
	}
}

The unit test. I need to mock the dao object to create a repeatable unit test of the service class. Here’s the code:

package my.app.service;

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

import my.app.dao.SupervisorDAO;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class SupervisorServiceUnitTest {

	@Mock private SupervisorDAO mockSupervisorDao;
	@InjectMocks private SupervisorService supervisorService;

	@Before
	public void init() {
		when(mockSupervisorDao.getUserCountForSupervisor(1, "Department1"))
			.thenReturn(2);
		when(mockSupervisorDao.getUserCountForSupervisor(1, "Department2"))
			.thenReturn(0);
	}

	@Test
	public void testIsSupervisorResponsibleForUserTrue() {
		boolean isSupervisor = supervisorService.isSupervisorResponsibleForUser(1, "Department1");
		assertTrue(isSupervisor);
	}

	@Test
	public void testIsSupervisorResponsibleForUserFalse() {
		boolean isSupervisor = supervisorService.isSupervisorResponsibleForUser(1, "Department2");
		assertFalse(isSupervisor);
	}

	@Test(expected=IllegalArgumentException.class)
	public void testIsSupervisorResponsibleRequiredDbId() {
		supervisorService.isSupervisorResponsibleForUser(0, "Department3");
	}

	@Test(expected=IllegalArgumentException.class)
	public void testIsSupervisorResponsibleRequiredDivision() {
		supervisorService.isSupervisorResponsibleForUser(1, null);
	}
}

The key things that I learned along the way:

  • Use @RunWith(MockitoJUnitRunner.class) to run this test
  • Use the @Mock annotation for the classes that need to be mocked within the class you are testing. Use the @InjectMocks annotation on the class you are testing. The @Mock classes are injected into the @InjectMocks class. I guess this should have been obvious, but it wasn’t to me.

It’s a simple class and a simple unit test, but it’s a start. It gets me over the hump of having the correct jars and knowing how to get a test up and running. I am new to the behavior driven style of Mockito, but this works well for me in this unit test. I think it is clean and easy to read.

Some links that were helpful to me (disclaimer, some of these are for older versions of Mockito)

Version Info:

  • Spring 3.0.5
  • Mockito 1.9.0
Advertisements

3 comments

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s