JAVA Unit Test for Spring Boot with Mockito and EasyMock

Here they are some ideas about testing using the different tools given by Spring Boot Test dependency. For me and my team they are so useful when we write and run the Unit Test for medium or high complexity classes.

Here they are some ideas about testing using the different tools given by Spring Boot Test dependency. Maybe some tips are not consider as the best practices by the Spring Boot, Mockito, EasyMock and/or TDD folllowers but for me and my team they are so useful when we write and run the Unit Test for medium or high complexity classes.
If you found a better solution for one or more cases or you want to share your best practices with us, please, let me know and I will update this post :).

Add the Maven dependencies

Add the Spring Boot starter test dependency to your pom.xml

		<!--  junit test with mockito -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

If you prefer to use EasyMock as the Unit Test framework, add the this dependency to your pom.xml

		<!-- junit test with easymock -->
		<dependency>
		    <groupId>org.easymock</groupId>
		    <artifactId>easymock</artifactId>
		    <version>3.4</version>
			<scope>test</scope>
		</dependency>

If you need to mock some environment variables or system properties in your Unit Test cases you can use the “system-rules” dependency:

		<!-- mocking environment variables -->
		<dependency>
			<groupId>com.github.stefanbirkner</groupId>
			<artifactId>system-rules</artifactId>
			<version>1.16.0</version>
			<scope>test</scope>
		</dependency>

Some Notes for Spring Boot
Spring Boot provides a number of utilities and annotations to help you when you are testing your application.
Test support is provided by two modules: spring-boot-test contains core items and spring-boot-test-autoconfigure supports auto-configuration for tests.
The ‘Starter’ dependency imports both Spring Boot test modules as well has JUnit, AssertJ, Hamcrest and a number of other useful libraries:

  • JUnit: The standard for unit testing Java applications
  • Spring Test & Spring Boot Test: Utilities and integration test support for Spring Boot applications
  • AssertJ: A fluent assertion library
  • Hamcrest: A library of matcher objects (also known as constraints or predicates)
  • Mockito: A Java mocking framework
  • JSONassert: An assertion library for JSON
  • JsonPath: XPath for JSON

Tips for Spring Boot 1.4.1.RELEASE or higher

  • @RunWith(SpringRunner.class): Use this annotation to invoke the Spring’s runner version 1.4 in Spring Boot Test and common JUnit tests
  • @SpringBootTest: Annotation that creates the Spring Application Context and runs the servlet container. Useful for integration test but too complex for simple JUnit test cases
  • @MockBean: Creates an instance of Bean mocking all their methods. You can define/change behaviors using Mockito’s clauses
  • @SpyBean: Creates an instance of Bean that invokes to their real methods, except you define particular behaviors using Mockito’s clauses

Tips for Spring Boot 1.3.8.RELEASE or lower

  • As Spring Boot uses a previous version of Mockito framewrok, you don’t have the @RunWith, @SpringBootTest, @MockBean and @SpyBean annotations

General tips for Mockito, JUnit and Hamcrest

  • Mock: Creates an instance of the class mocking all their methods. You can define/change behaviors using Mockito’s clauses (for example doXXX, when or given)
  • Spy: Creates an instance of the class that invokes to their real methods, except you define particular behaviors using Mockito’s clauses (for example doXXX, when or given)
  • WhiteBox: Part of Mockito. Useful to set values to private fields by reflection (probably is not a good TDD practice)
  • doReturn/when clause: Set expected return value for a mock instance when invoke a method. In some cases works instead of when or give clauses
  • doThrow/when clause: Set expected thrown exception for a mock instance when invoke a method
  • doNothing/when clause: Set expected no action for a mock instance when invoke a method. Useful for mock void methods
  • doXXX: You can chain expected results for more than one interaction: doReturn(first interction expected result).doReturn(second interaction expected result).when…
  • AnyXXX: Applies the behavior to any parameter do you use in the mock object
  • Verify: Used to verify the invocation of the mock, the number of interactions (or no interactions) with the mock (or a specific method), the order of interactions, if an interaction has occurred at least certain number of times, the arguments of the interaction, etc
  • @InjectMocks: Inject mocks only either by constructor injection, setter injection, or property injection in order. Useful for Spring Boot versions lower than 1.4
  • Use @Rule and ExpectedException to test the expected exceptions. Important: you have to define as public field in your test class
  • The Hamcrest matchers assertThat, equalTo, notNullValue are easy to use and very descriptive
  • Use @Before annotation for your setUp method (will be executed before each test method execution in your class)
  • Use @After annotation for your tearDown method (will be executed after each test method execution in your class)
  • If you need to mock system properties, system environment variables or other java.lang system features, you could use system-rules dependency

Example – Test a Spring Boot Controller

Controller Class

package com.example.sample.unit.test.SampleUnitTestsSB_141.controller;

import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.example.sample.unit.test.SampleUnitTestsSB_141.service.ExampleService;

/**
 * Handles the request for the example. 
 * @author Gabriel
 *
 */
@RestController
public class ExampleController {

	private static final Logger LOGGER = LoggerFactory.getLogger(ExampleController.class);
	
	@Autowired
	ExampleService exampleService;
	
	/**
	 * Gets all configured names.
	 * @return
	 */
	@RequestMapping(path="/test/get", produces= MediaType.APPLICATION_JSON_VALUE)
	public ResponseEntity<Map<String,String>> getAllNames() {
		LOGGER.info("getAllNames - start");
		ResponseEntity<Map<String,String>> responseEntity = null;
		
		try{
			Map<String,String> allNames = exampleService.getAllNames();
			responseEntity = new ResponseEntity<Map<String,String>>(allNames, HttpStatus.OK);
		} catch (Exception e) {
			Map<String,String> error = new HashMap<>();
			error.put("ERROR", e.getMessage());
			responseEntity = new ResponseEntity<Map<String,String>>(error, HttpStatus.BAD_REQUEST);
		}
		
		LOGGER.info("getAllNames - end");
		return responseEntity;		
	}	

}

Unit Test for the Controller Class using Mockito (with Spring Boot 1.4.1.RELEASE or higher)

package com.example.sample.unit.test.SampleUnitTestsSB_141.controller.mockito;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;

import com.example.sample.unit.test.SampleUnitTestsSB_141.controller.ExampleController;
import com.example.sample.unit.test.SampleUnitTestsSB_141.service.ExampleService;

import static org.hamcrest.MatcherAssert.assertThat;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.equalTo;

@RunWith(SpringRunner.class) // since 1.4.X version we can use this annotation to run the test using SB features
public class ExampleControllerTest {

	@Rule
	public ExpectedException thrown = ExpectedException.none();
	
	// SpyBean instantiates the subject of test, injects the mocked dependencies and invokes the real object methods
	@SpyBean
	private ExampleController exampleController;
	
	// mock the autowired dependency of the test subject		
	@MockBean
	ExampleService exampleServiceMock;
	
	// expect values to be returned by the controller
	private Map<String,String> expectedNames;
	
	// executed before each test case method -> initializes the expected values
	@Before
	public void setUp() {
		expectedNames = new HashMap<>();
		
		for (int i = 1; i < 6; i++) {
			expectedNames.put(String.valueOf(i), "Name "+ i);
		}
		
		// we don't need initializes the mocked objects and their dependencies -> Spring Boot doing that 🙂 
		// MockitoAnnotations.initMocks(this);
	}
	
	@Test
	public void getAllNamesWithValidArgumentsShouldReturnAResponseEntityWithMapOfNamesAndHttpStatusOK() throws Exception {
		// you can use in static way or do a static import
		Mockito.doReturn(expectedNames).when(exampleServiceMock).getAllNames();
		
		// invokes the test subject that uses the mocked behaviors		
		ResponseEntity<Map<String,String>> result = exampleController.getAllNames();
		
		// assert the expected results of the test case
		assertThat(result, notNullValue());
		assertThat(result.getStatusCode(), equalTo(HttpStatus.OK));
		assertThat(result.getBody(), notNullValue());
		assertThat(result.getBody().size(), equalTo(expectedNames.size()));
		assertThat(result.getBody().get("1"), equalTo(expectedNames.get("1"))); // should be "Name 1"
		assertThat(result.getBody().get("1"), equalTo("Name 1")); // another way for the previous assertion
		assertThat(result.getBody().get("2"), equalTo(expectedNames.get("2")));
		assertThat(result.getBody().get("3"), equalTo(expectedNames.get("3")));
		assertThat(result.getBody().get("4"), equalTo(expectedNames.get("4")));
		assertThat(result.getBody().get("5"), equalTo(expectedNames.get("5")));
		
		// indicates to Mockito that verifies if the mocked objects were called
		Mockito.verify(exampleServiceMock).getAllNames();
	}
	
	@Test
	public void getAllNamesWithValidArgumentsShouldReturnAResponseEntityWithErrorAndHttpStatusBadRequestWhenExampleServiceFails() throws Exception {
		SQLException expectedException = new SQLException("Some Expected Exception");
		
		// forces to throw an exception from the service to test the controller's catch code
		Mockito.doThrow(expectedException).when(exampleServiceMock).getAllNames();
		
		// invokes the test subject that uses the mocked behaviors		
		ResponseEntity<Map<String,String>> result = exampleController.getAllNames();
		
		// assert the expected results of the test case
		assertThat(result, notNullValue());
		assertThat(result.getStatusCode(), equalTo(HttpStatus.BAD_REQUEST));
		assertThat(result.getBody(), notNullValue());
		assertThat(result.getBody().size(), equalTo(1));
		// should be the message of the service exception
		assertThat(result.getBody().get("ERROR"), equalTo(expectedException.getMessage()));

		Mockito.verify(exampleServiceMock).getAllNames();		
	}
}

Unit Test for the Controller Class using Spring Boot MVC Test feature (with Spring Boot 1.4.1.RELEASE or higher)

package com.example.sample.unit.test.SampleUnitTestsSB_141.controller.mvc;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

import com.example.sample.unit.test.SampleUnitTestsSB_141.controller.ExampleController;
import com.example.sample.unit.test.SampleUnitTestsSB_141.service.ExampleService;

import net.minidev.json.JSONObject;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

@RunWith(SpringRunner.class) // since 1.4.X version we can use this annotation to run the test using SB features
@WebMvcTest(ExampleController.class) // performs a mvc unit test using the SB context (you can configure one for test purpose)
public class ExampleControllerTest {

	// Spring Boot class to perform restful operations
	@Autowired
	private MockMvc mockMVC;
	 
	// mock the autowired dependency of the test subject		
	@MockBean
	ExampleService exampleServiceMock;

	// expect values to be returned by the controller
	private Map<String,String> expectedNames;
	
	// executed before each test case method -> initializes the expected values
	@Before
	public void setUp() {
		expectedNames = new HashMap<>();
		
		for (int i = 1; i < 6; i++) {
			expectedNames.put(String.valueOf(i), "Name "+ i);
		}
	}
	
	@Test
	public void getAllNamesWithValidArgumentsShouldReturnAResponseEntityWithMapOfNamesAndHttpStatusOK() throws Exception {
		// you can use in static way or do a static import
		// mocks the DAO behavior to return the expected names list
		Mockito.doReturn(expectedNames).when(exampleServiceMock).getAllNames();

		this.mockMVC.perform(get("/test/get"))
				.andExpect(status().isOk())
	            .andExpect(content().string(new JSONObject(expectedNames).toJSONString()));

		// indicates to Mockito that verifies if the mocked objects were called
		Mockito.verify(exampleServiceMock).getAllNames();
	}

	@Test
	public void getAllNamesWithValidArgumentsShouldReturnAResponseEntityWithErrorAndHttpStatusBadRequestWhenExampleServiceFails() throws Exception {		
		// forces to throw an exception from the service to test the controller's catch block
		SQLException expectedException = new SQLException("Some Expected Exception");
		Mockito.doThrow(expectedException).when(exampleServiceMock).getAllNames();

		this.mockMVC.perform(get("/test/get"))
				.andExpect(status().isBadRequest())
	            .andExpect(content().string("{\"ERROR\":\"" +expectedException.getMessage()+ "\"}"));

		Mockito.verify(exampleServiceMock).getAllNames();		
	}
}

Unit Test for the Controller Class using Mockito (with Spring Boot 1.3.8.RELEASE or lower)

package com.example.sample.unit.test.SampleUnitTestsSB_138.controller.mockito;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

import com.example.sample.unit.test.SampleUnitTestsSB_138.controller.ExampleController;
import com.example.sample.unit.test.SampleUnitTestsSB_138.service.ExampleService;

import static org.hamcrest.MatcherAssert.assertThat;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.equalTo;

// we don't have the @RunWith(SpringRunner.class) annotation -> we use the pure Mockito annotations
public class ExampleControllerTest {

	@Rule
	public ExpectedException thrown = ExpectedException.none();
	
	// instantiates the subject of test and injects the mocked dependencies
	@InjectMocks // use to inject mocked objects in spring boot versions lower than 1.4
	private ExampleController exampleController;
	
	// mock the autowired dependency of the test subject	
	// we don't have the @MockBean in spring boot versions lower than 1.4 -> we use @Mock
	@Mock
	ExampleService exampleServiceMock;
	
	// expect values to be returned by the controller
	private Map<String,String> expectedNames;
	
	// executed before each test case method -> initializes the expected values
	@Before
	public void setUp() {
		expectedNames = new HashMap<>();
		
		for (int i = 1; i < 6; i++) {
			expectedNames.put(String.valueOf(i), "Name "+ i);
		}
		
		// initializes the mocked objects and injects the mocks to the object with @InjectMocks 
		MockitoAnnotations.initMocks(this);
	}
	
	@Test
	public void getAllNamesWithValidArgumentsShouldReturnAResponseEntityWithMapOfNamesAndHttpStatusOK() throws Exception {
		// you can use in static way or do a static import
		Mockito.doReturn(expectedNames).when(exampleServiceMock).getAllNames();
		
		// invokes the test subject that uses the mocked behaviors		
		ResponseEntity<Map<String,String>> result = exampleController.getAllNames();
		
		// assert the expected results of the test case
		assertThat(result, notNullValue());
		assertThat(result.getStatusCode(), equalTo(HttpStatus.OK));
		assertThat(result.getBody(), notNullValue());
		assertThat(result.getBody().size(), equalTo(expectedNames.size()));
		assertThat(result.getBody().get("1"), equalTo(expectedNames.get("1"))); // should be "Name 1"
		assertThat(result.getBody().get("1"), equalTo("Name 1")); // another way for the previous assertion
		assertThat(result.getBody().get("2"), equalTo(expectedNames.get("2")));
		assertThat(result.getBody().get("3"), equalTo(expectedNames.get("3")));
		assertThat(result.getBody().get("4"), equalTo(expectedNames.get("4")));
		assertThat(result.getBody().get("5"), equalTo(expectedNames.get("5")));
		
		// indicates to Mockito that verifies if the mocked objects were called
		Mockito.verify(exampleServiceMock).getAllNames();
	}
	
	@Test
	public void getAllNamesWithValidArgumentsShouldReturnAResponseEntityWithErrorAndHttpStatusBadRequestWhenExampleServiceFails() throws Exception {
		SQLException expectedException = new SQLException("Some Expected Exception");
		
		// forces to throw an exception from the service to test the controller's catch code
		Mockito.doThrow(expectedException).when(exampleServiceMock).getAllNames();
		
		// invokes the test subject that uses the mocked behaviors		
		ResponseEntity<Map<String,String>> result = exampleController.getAllNames();
		
		// assert the expected results of the test case
		assertThat(result, notNullValue());
		assertThat(result.getStatusCode(), equalTo(HttpStatus.BAD_REQUEST));
		assertThat(result.getBody(), notNullValue());
		assertThat(result.getBody().size(), equalTo(1));
		// should be the message of the service exception
		assertThat(result.getBody().get("ERROR"), equalTo(expectedException.getMessage()));

		Mockito.verify(exampleServiceMock).getAllNames();		
	}
}

Unit Test for the Controller Class using EasyMock

package com.example.sample.unit.test.SampleUnitTestsSB_141.controller.easymock;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import org.easymock.EasyMock;
import org.easymock.EasyMockRunner;
import org.easymock.Mock;
import org.easymock.TestSubject;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

import com.example.sample.unit.test.SampleUnitTestsSB_141.controller.ExampleController;
import com.example.sample.unit.test.SampleUnitTestsSB_141.service.ExampleService;

@RunWith(EasyMockRunner.class)
public class ExampleControllerTest {

	// instantiates the subject of test and injects the mocked dependencies
	@TestSubject
	ExampleController exampleController = new ExampleController();
	
	// mock the autowired dependency of the test subject
	@Mock
	ExampleService exampleServiceMock;
	
	// expect values to be returned by the controller
	private Map<String,String> expectedNames;
	
	// executed before each test case method -> initializes the expected values
	@Before
	public void setUp() {
		expectedNames = new HashMap<>();
		
		for (int i = 1; i < 6; i++) {
			expectedNames.put(String.valueOf(i), "Name "+ i);
		}
	}
	
	@Test
	public void getAllNamesWithValidArgumentsShouldReturnAResponseEntityWithMapOfNamesAndHttpStatusOK() throws Exception {
		// you can use in static way or do a static import
		// mocks the expected behavior for the service in this test case
		// important: you will test only the logic and the coverage of the test subject so mock the dependecies for that
		EasyMock.expect(exampleServiceMock.getAllNames()).andReturn(expectedNames);
		// indicates to EasyMock that has to "record" the expected behavior of mock objects
		EasyMock.replay(exampleServiceMock);
		
		// invokes the test subject that uses the mocked behaviors		
		ResponseEntity<Map<String,String>> result = exampleController.getAllNames();
		
		// assert the expected results of the test case
		assertThat(result, notNullValue());
		assertThat(result.getStatusCode(), equalTo(HttpStatus.OK));
		assertThat(result.getBody(), notNullValue());
		assertThat(result.getBody().size(), equalTo(expectedNames.size()));
		assertThat(result.getBody().get("1"), equalTo(expectedNames.get("1"))); // should be "Name 1"
		assertThat(result.getBody().get("1"), equalTo("Name 1")); // another way for the previous assertion
		assertThat(result.getBody().get("2"), equalTo(expectedNames.get("2")));
		assertThat(result.getBody().get("3"), equalTo(expectedNames.get("3")));
		assertThat(result.getBody().get("4"), equalTo(expectedNames.get("4")));
		assertThat(result.getBody().get("5"), equalTo(expectedNames.get("5")));
		
		// indicates to EasyMock that verifies if the mocked objects were called
		EasyMock.verify(exampleServiceMock);
	}

	@Test
	public void getAllNamesWithValidArgumentsShouldReturnAResponseEntityWithErrorAndHttpStatusBadRequestWhenExampleServiceFails() throws Exception {
		SQLException expectedException = new SQLException("Some Expected Exception");
		
		// forces to throw an exception from the service to test the controller's catch code
		EasyMock.expect(exampleServiceMock.getAllNames()).andThrow(expectedException);
		EasyMock.replay(exampleServiceMock);
		
		// invokes the test subject that uses the mocked behaviors		
		ResponseEntity<Map<String,String>> result = exampleController.getAllNames();
		
		// assert the expected results of the test case
		assertThat(result, notNullValue());
		assertThat(result.getStatusCode(), equalTo(HttpStatus.BAD_REQUEST));
		assertThat(result.getBody(), notNullValue());
		assertThat(result.getBody().size(), equalTo(1));
		// should be the message of the service exception
		assertThat(result.getBody().get("ERROR"), equalTo(expectedException.getMessage()));

		EasyMock.verify(exampleServiceMock);
	}	
}

Example – Test a Spring Boot Service

Service Class

package com.example.sample.unit.test.SampleUnitTestsSB_141.service;

import java.sql.SQLException;
import java.util.Map;

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

import com.example.sample.unit.test.SampleUnitTestsSB_141.dao.ExampleDAO;

/**
 * Services for the example.
 * @author Gabriel
 *
 */
@Service
public class ExampleService {
	
	@Autowired
	ExampleDAO exampleDAO;
	
	/**
	 * Gets all configured names.
	 * @return
	 * @throws SQLException
	 */
	public Map<String,String> getAllNames() throws SQLException {
		return exampleDAO.findAll();
	}
}

Unit Test for the Service Class using Mockito (with Spring Boot 1.4.1.RELEASE or higher)

package com.example.sample.unit.test.SampleUnitTestsSB_141.service.mockito;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.test.context.junit4.SpringRunner;

import com.example.sample.unit.test.SampleUnitTestsSB_141.dao.ExampleDAO;
import com.example.sample.unit.test.SampleUnitTestsSB_141.service.ExampleService;

import static org.hamcrest.MatcherAssert.assertThat;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.equalTo;

@RunWith(SpringRunner.class) // since 1.4.X version we can use this annotation to run the test using SB features
public class ExampleServiceTest {

	@Rule
	public ExpectedException thrown = ExpectedException.none();
	
	// SpyBean instantiates the subject of test, injects the mocked dependencies and invokes the real object methods
	@SpyBean
	private ExampleService exampleService;
	
	// mock the autowired dependency of the test subject		
	@MockBean
	ExampleDAO exampleDAOMock;
	
	// expect values to be returned by the service
	private Map<String,String> expectedNames;
	
	// executed before each test case method -> initializes the expected values
	@Before
	public void setUp() {
		expectedNames = new HashMap<>();
		
		for (int i = 1; i < 6; i++) {
			expectedNames.put(String.valueOf(i), "Name "+ i);
		}
		
		// we don't need initializes the mocked objects and their dependencies -> Spring Boot doing that 🙂 
		// MockitoAnnotations.initMocks(this);
	}
	
	@Test
	public void getAllNamesWithValidArgumentsShouldReturnAMapWithAllNames() throws Exception {
		// you can use in static way or do a static import
		Mockito.doReturn(expectedNames).when(exampleDAOMock).findAll();
		
		// invokes the test subject that uses the mocked behaviors		
		Map<String,String> result = exampleService.getAllNames();
		
		// assert the expected results of the test case
		assertThat(result, notNullValue());
		assertThat(result.size(), equalTo(expectedNames.size()));
		assertThat(result.get("1"), equalTo(expectedNames.get("1"))); // should be "Name 1"
		assertThat(result.get("1"), equalTo("Name 1")); // another way for the previous assertion
		assertThat(result.get("2"), equalTo(expectedNames.get("2")));
		assertThat(result.get("3"), equalTo(expectedNames.get("3")));
		assertThat(result.get("4"), equalTo(expectedNames.get("4")));
		assertThat(result.get("5"), equalTo(expectedNames.get("5")));
		
		// indicates to Mockito that verifies if the mocked objects were called
		Mockito.verify(exampleDAOMock).findAll();
	}
	
	@Test
	public void getAllNamesWithValidArgumentsShouldThrowASQLExceptionWhenDAOThrowsAnSQLException() throws Exception {
		SQLException expectedException = new SQLException("Some Expected DAO Exception");
		
		// should be before the test subject method invocation
		// indicates that the test case expects an exception of SQLException class with this message
		thrown.expect(SQLException.class);
		thrown.expectMessage(expectedException.getMessage());
								
		// forces to throw an exception from the service to test the controller's catch code
		Mockito.doThrow(expectedException).when(exampleDAOMock).findAll();
		
		// invokes the test subject that uses the mocked behaviors		
		// don't expect any assert because the service method should thrown an Exception
		exampleService.getAllNames();
				
		Mockito.verify(exampleDAOMock).findAll();		
	}
}

Unit Test for the Service Class using Mockito (with Spring Boot 1.3.8.RELEASE or lower)

package com.example.sample.unit.test.SampleUnitTestsSB_138.service.mockito;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;

import com.example.sample.unit.test.SampleUnitTestsSB_138.dao.ExampleDAO;
import com.example.sample.unit.test.SampleUnitTestsSB_138.service.ExampleService;

import static org.hamcrest.MatcherAssert.assertThat;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.equalTo;

// we don't have the @RunWith(SpringRunner.class) annotation -> we use the pure Mockito annotations
public class ExampleServiceTest {

	@Rule
	public ExpectedException thrown = ExpectedException.none();
	
	// instantiates the subject of test and injects the mocked dependencies
	@InjectMocks // use to inject mocked objects in spring boot versions lower than 1.4
	private ExampleService exampleService;
	
	// mock the autowired dependency of the test subject	
	// we don't have the @MockBean in spring boot versions lower than 1.4 -> we use @Mock
	@Mock
	ExampleDAO exampleDAOMock;
	
	// expect values to be returned by the service
	private Map<String,String> expectedNames;
	
	// executed before each test case method -> initializes the expected values
	@Before
	public void setUp() {
		expectedNames = new HashMap<>();
		
		for (int i = 1; i < 6; i++) {
			expectedNames.put(String.valueOf(i), "Name "+ i);
		}
		
		// initializes the mocked objects and injects the mocks to the object with @InjectMocks 
		MockitoAnnotations.initMocks(this);
	}
	
	@Test
	public void getAllNamesWithValidArgumentsShouldReturnAMapWithAllNames() throws Exception {
		// you can use in static way or do a static import
		Mockito.doReturn(expectedNames).when(exampleDAOMock).findAll();
		
		// invokes the test subject that uses the mocked behaviors		
		Map<String,String> result = exampleService.getAllNames();
		
		// assert the expected results of the test case
		assertThat(result, notNullValue());
		assertThat(result.size(), equalTo(expectedNames.size()));
		assertThat(result.get("1"), equalTo(expectedNames.get("1"))); // should be "Name 1"
		assertThat(result.get("1"), equalTo("Name 1")); // another way for the previous assertion
		assertThat(result.get("2"), equalTo(expectedNames.get("2")));
		assertThat(result.get("3"), equalTo(expectedNames.get("3")));
		assertThat(result.get("4"), equalTo(expectedNames.get("4")));
		assertThat(result.get("5"), equalTo(expectedNames.get("5")));
		
		// indicates to Mockito that verifies if the mocked objects were called
		Mockito.verify(exampleDAOMock).findAll();
	}
	
	@Test
	public void getAllNamesWithValidArgumentsShouldThrowASQLExceptionWhenDAOThrowsAnSQLException() throws Exception {
		SQLException expectedException = new SQLException("Some Expected DAO Exception");
		
		// should be before the test subject method invocation
		// indicates that the test case expects an exception of SQLException class with this message
		thrown.expect(SQLException.class);
		thrown.expectMessage(expectedException.getMessage());
								
		// forces to throw an exception from the service to test the controller's catch code
		Mockito.doThrow(expectedException).when(exampleDAOMock).findAll();
		
		// invokes the test subject that uses the mocked behaviors		
		// don't expect any assert because the service method should thrown an Exception
		exampleService.getAllNames();
				
		Mockito.verify(exampleDAOMock).findAll();		
	}
}

Unit Test for the Service Class using EasyMock

package com.example.sample.unit.test.SampleUnitTestsSB_141.service.easymock;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import org.easymock.EasyMock;
import org.easymock.EasyMockRunner;
import org.easymock.Mock;
import org.easymock.TestSubject;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;

import com.example.sample.unit.test.SampleUnitTestsSB_141.dao.ExampleDAO;
import com.example.sample.unit.test.SampleUnitTestsSB_141.service.ExampleService;

@RunWith(EasyMockRunner.class)
public class ExampleServiceTest {
	
	// instantiates the subject of test and injects the mocked dependencies
	@TestSubject
	ExampleService exampleService = new ExampleService();
	
	// mock the autowired dependency of the test subject
	@Mock
	ExampleDAO exampleDAOMock;

	// used to assert and catch the expected exceptions thrown by the test subject
	@Rule
	public ExpectedException thrown = ExpectedException.none();
	
	// expect values to be returned by the service
	private Map<String,String> expectedNames;
	
	// executed before each test case method -> initializes the expected values
	@Before
	public void setUp() {
		expectedNames = new HashMap<>();
		
		for (int i = 1; i < 6; i++) {
			expectedNames.put(String.valueOf(i), "Name "+ i);
		}
	}
	
	@Test
	public void getAllNamesWithValidArgumentsShouldReturnAMapWithAllNames() throws Exception {
		// you can use in static way or do a static import
		// mocks the expected behavior for the DAO in this test case
		// important: you will test only the logic and the coverage of the test subject so mock the dependecies for that
		EasyMock.expect(exampleDAOMock.findAll()).andReturn(expectedNames);
		// indicates to EasyMock that has to "record" the expected behavior of mock objects
		EasyMock.replay(exampleDAOMock);
		
		// invokes the test subject that uses the mocked behaviors		
		Map<String,String> result = exampleService.getAllNames();
		
		// assert the expected results of the test case
		assertThat(result, notNullValue());
		assertThat(result.size(), equalTo(expectedNames.size()));
		assertThat(result.get("1"), equalTo(expectedNames.get("1"))); // should be "Name 1"
		assertThat(result.get("1"), equalTo("Name 1")); // another way for the previous assertion
		assertThat(result.get("2"), equalTo(expectedNames.get("2")));
		assertThat(result.get("3"), equalTo(expectedNames.get("3")));
		assertThat(result.get("4"), equalTo(expectedNames.get("4")));
		assertThat(result.get("5"), equalTo(expectedNames.get("5")));
		
		// indicates to EasyMock that verifies if the mocked objects were called
		EasyMock.verify(exampleDAOMock);
	}

	@Test
	public void getAllNamesWithValidArgumentsShouldThrowASQLExceptionWhenDAOThrowsAnSQLException() throws Exception {
		SQLException expectedException = new SQLException("Some Expected DAO Exception");

		// should be before the test subject method invocation
		// indicates that the test case expects an exception of SQLException class with this message
		thrown.expect(SQLException.class);
		thrown.expectMessage(expectedException.getMessage());
				
		// forces to throw an exception from the service to test the controller's catch code
		EasyMock.expect(exampleDAOMock.findAll()).andThrow(expectedException);
		EasyMock.replay(exampleDAOMock);
		
		// invokes the test subject that uses the mocked behaviors		
		// don't expect any assert because the service method should thrown an Exception
		exampleService.getAllNames();
				
		EasyMock.verify(exampleDAOMock);
	}	
}

Example – Test a Spring Boot JDBC DAO

DAO Class

package com.example.sample.unit.test.SampleUnitTestsSB_141.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

@Repository
public class ExampleDAOImpl implements ExampleDAO {

	private static final Logger LOGGER = LoggerFactory.getLogger(ExampleDAOImpl.class);
	
	final static String QUERY_FIND_ALL = " SELECT * FROM TEST ";
	
	@Autowired
	DataSource dataSource;
	
	public Map<String,String> findAll() throws SQLException {
		Map<String,String> records = new HashMap<>();
		Connection connection = null;
		PreparedStatement preparedStatement = null;
		ResultSet resultSet = null;
		
		try {
			connection = dataSource.getConnection();
			preparedStatement = connection.prepareStatement(QUERY_FIND_ALL);
			resultSet = preparedStatement.executeQuery();
			
			while (resultSet.next()) {
				records.put(resultSet.getString(1), resultSet.getString(2));
			}
			
			return records;
		} catch (SQLException sqle) {
			LOGGER.error("Error performing query", sqle);
			throw sqle;
		} finally {
			closeSQLObject(resultSet, ResultSet.class.getName());
			closeSQLObject(preparedStatement, PreparedStatement.class.getName());
			closeSQLObject(connection, Connection.class.getName());
		}
	}
	
	/**
	 * Closes the given SQL AutoCloseable object.
	 * @param sqlObject
	 * @param sqlObjectType
	 */
	private void closeSQLObject(final AutoCloseable sqlObject, final String sqlObjectType) {
		try {
			sqlObject.close();
		} catch (Exception e) {
			LOGGER.warn("Exception closing : {}", sqlObjectType);
		}
	}
}

Unit Test for the DAO Class using Mockito (with Spring Boot 1.4.1.RELEASE or higher)

package com.example.sample.unit.test.SampleUnitTestsSB_141.dao.mockito;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.test.context.junit4.SpringRunner;

import com.example.sample.unit.test.SampleUnitTestsSB_141.dao.ExampleDAOImpl;

@RunWith(SpringRunner.class) // since 1.4.X version we can use this annotation to run the test using SB features
public class ExampleDAOImplTest {
	
	// include the query because if you change the query accidentally the test case will fail (it's a good checkpoint)
	final static String QUERY_FIND_ALL = " SELECT * FROM TEST ";
	
	// SpyBean instantiates the subject of test, injects the mocked dependencies and invokes the real object methods
	@SpyBean
	ExampleDAOImpl exampleDAOImpl;
	
	// mock the autowired dependency of the test subject		
	@MockBean
	DataSource dataSourceMock;
	
	// mocks the connection used by the DataSource mock
	@MockBean
	Connection connectionMock;
	// mocks the prepared statment used by the DataSource mock
	@MockBean
	PreparedStatement preparedStatementMock = null;
	// mocks the result set used by the DataSource mock
	@MockBean
	ResultSet resultSetMock = null;

	// used to assert and catch the expected exceptions thrown by the test subject
	@Rule
	public ExpectedException thrown = ExpectedException.none();
	
	// expect values to be returned by the dao
	private Map<String,String> expectedNames;
	
	// executed before each test case method -> initializes the expected values
	@Before
	public void setUp() {
		expectedNames = new HashMap<>();
		
		for (int i = 1; i < 6; i++) {
			expectedNames.put(String.valueOf(i), "Name "+ i);
		}
		
		// we don't need initializes the mocked objects and their dependencies -> Spring Boot doing that 🙂 
		// MockitoAnnotations.initMocks(this);
	}
	
	@Test
	public void findAllWithValidArgumentsShouldReturnAMapWithAllNames() throws Exception {
		// you can use in static way or do a static import
		// mocks the expected behavior for the DAO in this test case
		// important: you will test only the logic and the coverage of the test subject so mock the dependencies for that
		Mockito.doReturn(connectionMock).when(dataSourceMock).getConnection();
		Mockito.doReturn(preparedStatementMock).when(connectionMock).prepareStatement(QUERY_FIND_ALL);
		Mockito.doReturn(resultSetMock).when(preparedStatementMock).executeQuery();
		
		// mocks the ResultSet iteration and sets the expect results
		// you can chain the expected behavior of the iteration
		Mockito.doReturn(true).doReturn(true).doReturn(true).doReturn(true).doReturn(true).doReturn(false).when(resultSetMock).next();
		Mockito.doReturn("1").doReturn("2").doReturn("3").doReturn("4").doReturn("5").when(resultSetMock).getString(1);
		Mockito.doReturn(expectedNames.get("1"))
			.doReturn(expectedNames.get("2"))
			.doReturn(expectedNames.get("3"))
			.doReturn(expectedNames.get("4"))
			.doReturn(expectedNames.get("5"))
			.when(resultSetMock).getString(2);
		
		// mocks the finally block
		Mockito.doNothing().when(resultSetMock).close(); // the close method is a void method so you don't expect any result
		Mockito.doNothing().when(preparedStatementMock).close();
		Mockito.doNothing().when(connectionMock).close();
		
		// invokes the test subject that uses the mocked behaviors		
		Map<String,String> result = exampleDAOImpl.findAll();
		
		// assert the expected results of the test case
		assertThat(result, notNullValue());
		assertThat(result.size(), equalTo(expectedNames.size()));
		assertThat(result.get("1"), equalTo(expectedNames.get("1"))); // should be "Name 1"
		assertThat(result.get("1"), equalTo("Name 1")); // another way for the previous assertion
		assertThat(result.get("2"), equalTo(expectedNames.get("2")));
		assertThat(result.get("3"), equalTo(expectedNames.get("3")));
		assertThat(result.get("4"), equalTo(expectedNames.get("4")));
		assertThat(result.get("5"), equalTo(expectedNames.get("5")));
		
		// indicates to Mockito that verifies if the mocked objects were called
		Mockito.verify(dataSourceMock).getConnection();
		// you should include Mockito.verify for each mocked method and object
	}

	@Test
	public void findAllWithValidArgumentsShouldThrowASQLExceptionWhenGetConnectionThrowsAnException() throws Exception {
		SQLException expectedException = new SQLException("Get Connection Exception");

		// should be before the test subject method invocation
		// indicates that the test case expects an exception of SQLException class with this message
		thrown.expect(SQLException.class);
		thrown.expectMessage(expectedException.getMessage());
				
		// forces to throw an exception from the service to test the controller's catch code
		Mockito.doThrow(expectedException).when(dataSourceMock).getConnection();
		
		// mocks the finally block
		Mockito.doNothing().when(resultSetMock).close(); // the close method is a void method so you don't expect any result
		Mockito.doNothing().when(preparedStatementMock).close();
		Mockito.doNothing().when(connectionMock).close();

		// invokes the test subject that uses the mocked behaviors		
		// don't expect any assert because the DAO method should thrown an Exception
		exampleDAOImpl.findAll();
				
		Mockito.verify(dataSourceMock).getConnection();
		// you should include Mockito.verify for each mocked method and object
	}	
}

Unit Test for the DAO Class using Mockito (with Spring Boot 1.3.8.RELEASE or lower)

package com.example.sample.unit.test.SampleUnitTestsSB_138.dao.mockito;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;

import com.example.sample.unit.test.SampleUnitTestsSB_138.dao.ExampleDAOImpl;

//we don't have the @RunWith(SpringRunner.class) annotation -> we use the pure Mockito annotations
public class ExampleDAOImplTest {
	
	// include the query because if you change the query accidentally the test case will fail (it's a good checkpoint)
	final static String QUERY_FIND_ALL = " SELECT * FROM TEST ";
	
	// instantiates the subject of test and injects the mocked dependencies
	@InjectMocks // use to inject mocked objects in spring boot versions lower than 1.4
	ExampleDAOImpl exampleDAOImpl;
	
	// mock the autowired dependency of the test subject	
	// we don't have the @MockBean in spring boot versions lower than 1.4 -> we use @Mock
	@Mock
	DataSource dataSourceMock;
	// mocks the connection used by the DataSource mock
	@Mock
	Connection connectionMock;
	// mocks the prepared statment used by the DataSource mock
	@Mock
	PreparedStatement preparedStatementMock = null;
	// mocks the result set used by the DataSource mock
	@Mock
	ResultSet resultSetMock = null;

	// used to assert and catch the expected exceptions thrown by the test subject
	@Rule
	public ExpectedException thrown = ExpectedException.none();
	
	// expect values to be returned by the dao
	private Map<String,String> expectedNames;
	
	// executed before each test case method -> initializes the expected values
	@Before
	public void setUp() {
		expectedNames = new HashMap<>();
		
		for (int i = 1; i < 6; i++) {
			expectedNames.put(String.valueOf(i), "Name "+ i);
		}
		
		// initializes the mocked objects and injects the mocks to the object with @InjectMocks 
		MockitoAnnotations.initMocks(this);
	}
	
	@Test
	public void findAllWithValidArgumentsShouldReturnAMapWithAllNames() throws Exception {
		// you can use in static way or do a static import
		// mocks the expected behavior for the DAO in this test case
		// important: you will test only the logic and the coverage of the test subject so mock the dependencies for that
		Mockito.doReturn(connectionMock).when(dataSourceMock).getConnection();
		Mockito.doReturn(preparedStatementMock).when(connectionMock).prepareStatement(QUERY_FIND_ALL);
		Mockito.doReturn(resultSetMock).when(preparedStatementMock).executeQuery();
		
		// mocks the ResultSet iteration and sets the expect results
		// you can chain the expected behavior of the iteration
		Mockito.doReturn(true).doReturn(true).doReturn(true).doReturn(true).doReturn(true).doReturn(false).when(resultSetMock).next();
		Mockito.doReturn("1").doReturn("2").doReturn("3").doReturn("4").doReturn("5").when(resultSetMock).getString(1);
		Mockito.doReturn(expectedNames.get("1"))
			.doReturn(expectedNames.get("2"))
			.doReturn(expectedNames.get("3"))
			.doReturn(expectedNames.get("4"))
			.doReturn(expectedNames.get("5"))
			.when(resultSetMock).getString(2);
		
		// mocks the finally block
		Mockito.doNothing().when(resultSetMock).close(); // the close method is a void method so you don't expect any result
		Mockito.doNothing().when(preparedStatementMock).close();
		Mockito.doNothing().when(connectionMock).close();
		
		// invokes the test subject that uses the mocked behaviors		
		Map<String,String> result = exampleDAOImpl.findAll();
		
		// assert the expected results of the test case
		assertThat(result, notNullValue());
		assertThat(result.size(), equalTo(expectedNames.size()));
		assertThat(result.get("1"), equalTo(expectedNames.get("1"))); // should be "Name 1"
		assertThat(result.get("1"), equalTo("Name 1")); // another way for the previous assertion
		assertThat(result.get("2"), equalTo(expectedNames.get("2")));
		assertThat(result.get("3"), equalTo(expectedNames.get("3")));
		assertThat(result.get("4"), equalTo(expectedNames.get("4")));
		assertThat(result.get("5"), equalTo(expectedNames.get("5")));
		
		// indicates to Mockito that verifies if the mocked objects were called
		Mockito.verify(dataSourceMock).getConnection();
		// you should include Mockito.verify for each mocked method and object
	}

	@Test
	public void findAllWithValidArgumentsShouldThrowASQLExceptionWhenGetConnectionThrowsAnException() throws Exception {
		SQLException expectedException = new SQLException("Get Connection Exception");

		// should be before the test subject method invocation
		// indicates that the test case expects an exception of SQLException class with this message
		thrown.expect(SQLException.class);
		thrown.expectMessage(expectedException.getMessage());
				
		// forces to throw an exception from the service to test the controller's catch code
		Mockito.doThrow(expectedException).when(dataSourceMock).getConnection();
		
		// mocks the finally block
		Mockito.doNothing().when(resultSetMock).close(); // the close method is a void method so you don't expect any result
		Mockito.doNothing().when(preparedStatementMock).close();
		Mockito.doNothing().when(connectionMock).close();

		// invokes the test subject that uses the mocked behaviors		
		// don't expect any assert because the DAO method should thrown an Exception
		exampleDAOImpl.findAll();
				
		Mockito.verify(dataSourceMock).getConnection();
		// you should include Mockito.verify for each mocked method and object
	}	
}

Unit Test for the DAO Class using EasyMock

package com.example.sample.unit.test.SampleUnitTestsSB_141.dao.easymock;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.easymock.EasyMock;
import org.easymock.EasyMockRunner;
import org.easymock.Mock;
import org.easymock.TestSubject;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;

import com.example.sample.unit.test.SampleUnitTestsSB_141.dao.ExampleDAOImpl;

@RunWith(EasyMockRunner.class)
public class ExampleDAOImplTest {
	// include the query because if you change the query accidentally the test case will fail (it's a good checkpoint)
	final static String QUERY_FIND_ALL = " SELECT * FROM TEST ";
	
	// instantiates the subject of test and injects the mocked dependencies
	@TestSubject
	ExampleDAOImpl exampleDAOImpl = new ExampleDAOImpl();
	
	// mocks the autowired dependency of the test subject
	@Mock
	DataSource dataSourceMock;
	// mocks the connection used by the DataSource mock
	@Mock
	Connection connectionMock;
	// mocks the prepared statment used by the DataSource mock
	@Mock
	PreparedStatement preparedStatementMock = null;
	// mocks the result set used by the DataSource mock
	@Mock
	ResultSet resultSetMock = null;

	// used to assert and catch the expected exceptions thrown by the test subject
	@Rule
	public ExpectedException thrown = ExpectedException.none();
	
	// expect values to be returned by the dao
	private Map<String,String> expectedNames;
	
	// executed before each test case method -> initializes the expected values
	@Before
	public void setUp() {
		expectedNames = new HashMap<>();
		
		for (int i = 1; i < 6; i++) {
			expectedNames.put(String.valueOf(i), "Name "+ i);
		}
	}
	
	@Test
	public void findAllWithValidArgumentsShouldReturnAMapWithAllNames() throws Exception {
		// you can use in static way or do a static import
		// mocks the expected behavior for the DAO in this test case
		// important: you will test only the logic and the coverage of the test subject so mock the dependencies for that
		EasyMock.expect(dataSourceMock.getConnection()).andReturn(connectionMock);
		EasyMock.expect(connectionMock.prepareStatement(QUERY_FIND_ALL)).andReturn(preparedStatementMock);
		EasyMock.expect(preparedStatementMock.executeQuery()).andReturn(resultSetMock);
		
		// mocks the ResultSet iteration and sets the expect results
		EasyMock.expect(resultSetMock.next()).andReturn(true);
		EasyMock.expect(resultSetMock.getString(1)).andReturn("1");
		EasyMock.expect(resultSetMock.getString(2)).andReturn(expectedNames.get("1"));
		EasyMock.expect(resultSetMock.next()).andReturn(true);
		EasyMock.expect(resultSetMock.getString(1)).andReturn("2");
		EasyMock.expect(resultSetMock.getString(2)).andReturn(expectedNames.get("2"));
		EasyMock.expect(resultSetMock.next()).andReturn(true);
		EasyMock.expect(resultSetMock.getString(1)).andReturn("3");
		EasyMock.expect(resultSetMock.getString(2)).andReturn(expectedNames.get("3"));
		EasyMock.expect(resultSetMock.next()).andReturn(true);
		EasyMock.expect(resultSetMock.getString(1)).andReturn("4");
		EasyMock.expect(resultSetMock.getString(2)).andReturn(expectedNames.get("4"));
		EasyMock.expect(resultSetMock.next()).andReturn(true);
		EasyMock.expect(resultSetMock.getString(1)).andReturn("5");
		EasyMock.expect(resultSetMock.getString(2)).andReturn(expectedNames.get("5"));
		EasyMock.expect(resultSetMock.next()).andReturn(false);
		
		// mocks the finally block
		resultSetMock.close(); // the close method is a void method so you don't expect any result
		EasyMock.expectLastCall(); // for the void method use expectLastCall
		preparedStatementMock.close();
		EasyMock.expectLastCall();
		connectionMock.close();
		EasyMock.expectLastCall();
		
		// indicates to EasyMock that has to "record" the expected behavior of mock objects
		EasyMock.replay(dataSourceMock, connectionMock, preparedStatementMock, resultSetMock);
		
		// invokes the test subject that uses the mocked behaviors		
		Map<String,String> result = exampleDAOImpl.findAll();
		
		// assert the expected results of the test case
		assertThat(result, notNullValue());
		assertThat(result.size(), equalTo(expectedNames.size()));
		assertThat(result.get("1"), equalTo(expectedNames.get("1"))); // should be "Name 1"
		assertThat(result.get("1"), equalTo("Name 1")); // another way for the previous assertion
		assertThat(result.get("2"), equalTo(expectedNames.get("2")));
		assertThat(result.get("3"), equalTo(expectedNames.get("3")));
		assertThat(result.get("4"), equalTo(expectedNames.get("4")));
		assertThat(result.get("5"), equalTo(expectedNames.get("5")));
		
		// indicates to EasyMock that verifies if the mocked objects were called
		EasyMock.verify(dataSourceMock, connectionMock, preparedStatementMock, resultSetMock);
	}

	@Test
	public void findAllWithValidArgumentsShouldThrowASQLExceptionWhenGetConnectionThrowsAnException() throws Exception {
		SQLException expectedException = new SQLException("Get Connection Exception");

		// should be before the test subject method invocation
		// indicates that the test case expects an exception of SQLException class with this message
		thrown.expect(SQLException.class);
		thrown.expectMessage(expectedException.getMessage());
				
		// forces to throw an exception from the service to test the controller's catch code
		EasyMock.expect(dataSourceMock.getConnection()).andThrow(expectedException);
		
		// mocks the finally block
		resultSetMock.close(); // the close method is a void method so you don't expect any result
		EasyMock.expectLastCall(); // for the void method use expectLastCall
		preparedStatementMock.close();
		EasyMock.expectLastCall();
		connectionMock.close();
		EasyMock.expectLastCall();

		EasyMock.replay(dataSourceMock, connectionMock, preparedStatementMock, resultSetMock);
		
		// invokes the test subject that uses the mocked behaviors		
		// don't expect any assert because the DAO method should thrown an Exception
		exampleDAOImpl.findAll();
				
		EasyMock.verify(dataSourceMock);
	}	
}

Useful documentation and examples
Online Training:

About TDD:

About Spring Boot Test:

About Mockito

About system-rules dependency:

Final notes
The Application and their Unit Tests were tested with Spring Boot versions: 1.5.4.RELEASE, 1.4.1.RELEASE and 1.3.8.RELEASE (without ServletInitiliazer class)

You can get the complete code from my public GitHub repository:
https://github.com/Gabotto/SampleUnitTests

Let me know if you have any problem, comment or new ideas:
WordPress: https://gabelopment.wordpress.com/
Email: gabelopment@gmail.com

Also you can find me at Upwork

See you soon with more development notes…

Author: Gabi

Senior Backend Software Engineer with more than 20 years of experience working as a Developer, Architect / Software Engineer, Technical Lead and Team Manager for industries such as TELCO, Media, Insurance, Finance and AI. I'm a "fan" of the Agile methodology and development patterns & principles like KISS, YAGNI or DRY. I really enjoy being an SME in my projects, studying and learning new technologies, researching how to solve problems in an innovative, optimal and simple way, following and sharing good practices, clean code and software design principles & patterns with my teams and co-workers. I love to build effective teams in a collaborative work environment!

Leave a comment