Spring Boot Unit Testing Example
1. Introduction
This is an in-depth article related to the Spring Boot Unit Testing. Spring Boot framework has features to build applications. Spring Boot has features related to unit testing the application. The framework has utilities and annotations to perform unit testing. Modules for the Test support are spring-boot-test and spring-boot-test-autoconfigure which supports auto-configuration for tests.
2. Spring Boot Unit Testing
2.1 Prerequisites
Java 8 or 9 is required on the linux, windows or mac operating system. Maven 3.6.1 is required for building the spring and hibernate application.
2.2 Download
You can download Java 8 can be downloaded from the Oracle web site . Apache Maven 3.6.1 can be downloaded fromApache site. Spring framework latest releases are available from the spring website.
2.3 Setup
You can set the environment variables for JAVA_HOME and PATH. They can be set as shown below:
Environment Setup for Java
1 2 3 4 | JAVA_HOME=”/jboss/jdk1.8.0_73″ export JAVA_HOME PATH=$JAVA_HOME/bin:$PATH export PATH |
The environment variables for maven are set as below:
Environment Setup for Maven
1 2 3 4 | JAVA_HOME=”/jboss/jdk1.8.0_73″ export M2_HOME=/users/bhagvan.kommadi/Desktop/apache-maven-3.6.1 export M2=$M2_HOME/bin export PATH=$M2:$PATH |
2.4 Building the application
2.4.1 Spring
You can start building Spring applications using Spring Boot framework. Spring Boot has minimal configuration of Spring. Spring Boot has features related to security, tracing, application health management and runtime support for webservers. Spring configuration is done through maven pom.xml. The xml configuration is shown as below:
Spring Configuration
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | <? xml version = "1.0" encoding = "UTF-8" ?> < project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" > < modelVersion >4.0.0</ modelVersion > < groupId >org.springframework</ groupId > < artifactId >spring-helloworld</ artifactId > < version >0.1.0</ version > < parent > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-starter-parent</ artifactId > < version >2.1.4.RELEASE</ version > </ parent > < dependencies > < dependency > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-starter-web</ artifactId > </ dependency > < dependency > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-starter-test</ artifactId > < scope >test</ scope > </ dependency > </ dependencies > < properties > < java.version >1.8</ java.version > </ properties > < build > < plugins > < plugin > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-maven-plugin</ artifactId > </ plugin > </ plugins > </ build > </ project > |
You can create a HelloWorldController
class as the web controller. The class is annotated using @RestController
. Rest Controller is used to handle requests in Spring Model View Controller framework. Annotation @RequestMapping
is used to annotate the index()
method. The code for the HelloWorldController
class is shown below:
HelloWorld Controller
01 02 03 04 05 06 07 08 09 10 11 12 13 | package helloworld; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RequestMapping; @RestController public class HelloWorldController { @RequestMapping ( "/" ) public String index() { return "Hello World\n" ; } } |
HelloWorldApp
is created as the Spring Boot web application. When the application starts, beans, and settings are wired up dynamically. They are applied to the application context. The code for HelloWorldApp
class is shown below:
HelloWorld App
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | package helloworld; import java.util.Arrays; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; @SpringBootApplication public class HelloWorldApp { public static void main(String[] args) { ApplicationContext ctx = SpringApplication.run(HelloWorldApp. class , args); System.out.println( "Inspecting the beans" ); String[] beans = ctx.getBeanDefinitionNames(); Arrays.sort(beans); for (String name : beans) { System.out.println( "Bean Name" +name); } } } |
Maven is used for building the application. The command below builds the application.
Maven Build Command
1 | mvn package |
The output of the executed command is shown below.

The jar file spring-helloworld-0.1.0.jar is created. The following command is used for executing the jar file.
Run Command
1 | java -jar target/spring-helloworld-0.1.0.jar |
The output of the executed command is shown below.

Curl command is invoked on the command line for the execution of index
method. The method returns a String “Hello World” text. @RestController
aggregates the two annotations @Controller
and @ResponseBody
. This results in returning data. The ouput is shown as below.

2.5 Unit Testing
2.5.1 Mocks
In Spring, MockMvc
is used to send HTTP requests to the DispatcherServlet
. The assertions are made based on the result obtained from the servlet. @AutoConfigureMockMvc
annotation is used with @SpringBootTest
to inject a MockMvc
instance. The implementation of the Spring Unit Test is shown as below:
HelloWorldControllerTest
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | package helloworld; import static org.hamcrest.Matchers.equalTo; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; @RunWith (SpringRunner. class ) @SpringBootTest @AutoConfigureMockMvc public class HelloWorldControllerTest { @Autowired private MockMvc mvc; @Test public void getMessage() throws Exception { mvc.perform(MockMvcRequestBuilders.get( "/" ).accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().string(equalTo( "Hello World\n" ))); } } |
Maven command is used to run the unit test. The command is as below :
Maven Build Command
1 | mvn package |
The output of the executed command is shown below.

2.5.2 No Mocks
Spring configuration of unit tests without Mocks is done through maven pom.xml. The xml configuration is shown as below:
Maven pom.xml
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | <? xml version = "1.0" encoding = "UTF-8" ?> < project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" > < modelVersion >4.0.0</ modelVersion > < parent > <!-- Your own application should inherit from spring-boot-starter-parent --> < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-examples</ artifactId > < version >${revision}</ version > </ parent > < artifactId >spring-boot-example-test-nomockito</ artifactId > < name >Spring Boot Test Sample No Mockito</ name > < description >Spring Boot Test Sample No Mockito</ description > < properties > < main.basedir >${basedir}/../..</ main.basedir > </ properties > < dependencies > <!-- Compile --> < dependency > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-starter</ artifactId > </ dependency > <!-- Test --> < dependency > < groupId >junit</ groupId > < artifactId >junit</ artifactId > < scope >test</ scope > </ dependency > < dependency > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-test</ artifactId > < scope >test</ scope > </ dependency > < dependency > < groupId >org.springframework</ groupId > < artifactId >spring-test</ artifactId > < scope >test</ scope > </ dependency > < dependency > < groupId >org.assertj</ groupId > < artifactId >assertj-core</ artifactId > < scope >test</ scope > </ dependency > </ dependencies > < build > < plugins > < plugin > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-maven-plugin</ artifactId > </ plugin > </ plugins > </ build > </ project > |
ExampleTestNoMockitoApplication
is created as the Spring Boot web application. When the application starts, beans, and settings are wired up dynamically. They are applied to the application context. The code for ExampleTestNoMockitoApplication
class is shown below:
ExampleTestNoMockitoApplication
01 02 03 04 05 06 07 08 09 10 11 12 13 14 | package example.testnomockito; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class ExampleTestNoMockitoApplication { public static void main(String[] args) { SpringApplication.run(ExampleTestNoMockitoApplication. class ); } } |
The implementation of the Spring Unit Test is shown as below:
Unit Test without Mocks
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | package example.testnomockito; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.test.context.junit4.SpringRunner; import static org.assertj.core.api.Assertions.assertThat; @RunWith (SpringRunner. class ) public class ExampleTestNoMockitoApplicationTests { @Autowired private ApplicationContext context; @Test public void contextLoads() throws Exception { assertThat( this .context).isNotNull(); } } |
Maven command is used to run the unit test. The command is as below :
Maven Build Command
1 | mvn package |
The output of the executed command is shown below.

2.5.3 TestNG
TestNG is a unit testing framework for unit testing Spring Boot applications. This framework is inspired from JUnit and NUnit. TestNG is an open source automated testing framework. Spring configuration of unit tests with TestNG is done through maven pom.xml. The xml configuration is shown as below:
Maven pom.xml
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | <? xml version = "1.0" encoding = "UTF-8" ?> < project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" > < modelVersion >4.0.0</ modelVersion > < parent > <!-- Your own application should inherit from spring-boot-starter-parent --> < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-examples</ artifactId > < version >${revision}</ version > </ parent > < artifactId >spring-boot-example-testng</ artifactId > < name >Spring Boot TestNG Sample</ name > < description >Spring Boot TestNG Sample</ description > < properties > < main.basedir >${basedir}/../..</ main.basedir > </ properties > < dependencies > <!-- Compile --> < dependency > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-starter</ artifactId > </ dependency > < dependency > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-starter-tomcat</ artifactId > </ dependency > < dependency > < groupId >org.springframework</ groupId > < artifactId >spring-webmvc</ artifactId > </ dependency > <!-- Test --> < dependency > < groupId >org.springframework</ groupId > < artifactId >spring-test</ artifactId > < scope >test</ scope > </ dependency > < dependency > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-test</ artifactId > < scope >test</ scope > </ dependency > < dependency > < groupId >org.testng</ groupId > < artifactId >testng</ artifactId > < version >6.8.13</ version > < scope >test</ scope > </ dependency > < dependency > < groupId >org.assertj</ groupId > < artifactId >assertj-core</ artifactId > < scope >test</ scope > </ dependency > </ dependencies > < build > < plugins > < plugin > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-maven-plugin</ artifactId > </ plugin > </ plugins > </ build > </ project > |
ExampleTestNGApplication
is created as the Spring Boot web application. When the application starts, beans, and settings are wired up dynamically. They are applied to the application context. The code for ExampleTestNGApplication
class is shown below:
ExampleTestNGApplication
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | package example.testng; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; @SpringBootApplication public class ExampleTestNGApplication { private static Log logger = LogFactory.getLog(ExampleTestNGApplication. class ); @Bean protected ServletContextListener listener() { return new ServletContextListener() { @Override public void contextInitialized(ServletContextEvent sce) { logger.info( "ServletContext initialized" ); } @Override public void contextDestroyed(ServletContextEvent sce) { logger.info( "ServletContext destroyed" ); } }; } public static void main(String[] args) { SpringApplication.run(ExampleTestNGApplication. class , args); } } |
The implementation of the Message Service Class is shown as below:
Message Service
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 | package example.testng.service; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class MessageService { @Value ( "${name:Greeting}" ) private String name; public String getMessage() { return "Sending " + this .name; } } |
The implementation of the ExampleController class is shown as below:
ExampleController
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 | package example.testng.web; import example.testng.service.MessageService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class ExampleController { @Autowired private MessageService messageService; @GetMapping ( "/" ) @ResponseBody public String greeting() { return this .messageService.getMessage(); } } |
The implementation of the Spring Unit Test is shown as below:
ExampleTestNGApplicationTests
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | package example.testng; import org.testng.annotations.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest (webEnvironment = WebEnvironment.RANDOM_PORT) public class ExampleTestNGApplicationTests extends AbstractTestNGSpringContextTests { @Autowired private TestRestTemplate restTemplate; @Test public void testHome() { ResponseEntity entity = this .restTemplate.getForEntity( "/" , String. class ); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); assertThat(entity.getBody()).isEqualTo( "Sending Greeting" ); } } |
Maven command is used to run the unit test. The command is as below :
Maven Build Command
1 | mvn package |
The output of the executed command is shown below.

2.5.4 Auto Configurations
Auto-configuration is the feature of Spring 2.0 framework. Tests for auto-configuration classes start up an ApplicationContext
with the auto-configuration class. AutoConfigurations
class can be under test or dependent on the test., The sample code which shows the autoconfiguration is attached below:
Auto Configuration
1 | private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(MessageServiceAutoConfiguration. class )); |
2.5.5 Smoke Test
The @SpringBootTest
annotation is used in Spring Boot Framework based Smoke Tests. The main configuration class has the annotation @SpringBootApplication
at the declaration of the class. A sample SmokeTest
implementation is shown as below:
Smoke Test
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 | import static org.assertj.core.api.Assertions.assertThat; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith (SpringRunner. class ) @SpringBootTest public class SmokeTest { @Autowired private ExampleController controller; @Test public void contexLoads() throws Exception { assertThat(controller).isNotNull(); } } |
2.5.6 Application Behavior
You can write unit tests which assert the application behavior. The application can start up and listen for a connection. The HTTP request can be sent and the response is asserted. A sample class TestHttpRequest
which implements the unit test for application behavior is shown below.
TestHttpRequest
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.test.context.junit4.SpringRunner; import static org.assertj.core.api.Assertions.assertThat; @RunWith (SpringRunner. class ) @SpringBootTest (webEnvironment = WebEnvironment.RANDOM_PORT) public class TestHttpRequest { @LocalServerPort private int port; @Autowired private TestRestTemplate restTemplate; @Test public void greetingShouldReturnDefaultMessage() throws Exception { String. class )).contains("Greetings Message); } } |
2.6 Full Stack Integration Test
Integration test is used for testing the communication paths between different parts of the module. This is done to ensure that all modules work rightly. You can use Spring Boot to write a full-stack integration test. Sample Full Stack Integration test is implemented for the application built in section 2.4.
Full Stack Integration Test
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | package helloworld; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import java.net.URL; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit4.SpringRunner; @RunWith (SpringRunner. class ) @SpringBootTest (webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class HelloWorldControllerIntegrationTest { @LocalServerPort private int port; private URL base; @Autowired private TestRestTemplate template; @Before public void setUp() throws Exception { } @Test public void getMessage() throws Exception { ResponseEntity response = template.getForEntity(base.toString(), String. class ); assertThat(response.getBody(), equalTo( "Hello World\n" )); } } |
Maven command is used to run the unit test. The command is as below :
Maven Build Command
1 | mvn package |
The output of the executed command is shown below.

2.6 Auto-Configured Tests
You can use the @WebFluxTest
annotation to test the Spring controllers based on Spring Webflux framework. @MockBean
annotation is used to provide mock implementations. @JdbcTest
annotation is used to test JPA applications. @JdbcTest
annotation configures the data source as an in-memory embedded database. @JooqTest
annotation configures a DSLContext. @DataMongoTest
annotation configures an in-memory embedded MongoDB database. This annotation configures a MongoTemplate
. MongoTemplate
scans for @Document
classes. The template configures Spring Data MongoDB database repositories.@DataRedisTest
annotation is used to test Redis applications. The annotation scans for the classes which use @RedisHash annotation. @DataRedisTest
annotation configures the Spring Data Redis database repositories.
@DataLdapTest
annotation configures an in-memory embedded LDAP. This annotation configures a LdapTemplate
. It also scans for @Entry
classes and configures Spring Data LDAP repositories. You can use the @RestClientTest
annotation to test the REST clients. @RestClientTest
annotation auto-configures the dependencies like Jackson, GSON, and Jsonb support. This annotation configures a RestTemplateBuilder
. It also adds support for the MockRestServiceServer
.
2.7 Best Practices
You can isolate the functionality to be unit tested. This is done by limiting the context of loaded frameworks and components. The slices of functionality are loaded when testing spring boot applications. The other best practices are available at the spring boot testing site.
2.8 Error Handling
Spring boot framework has features to handle exceptions and errors. Errors in REST APIs help in presenting the issues to the clients. You can use @ResponseStatus
annotation to specify the Response Status for a specific exception.
2.9 Logging
Spring Boot Framework uses Commons Logging for application logging. Different configurations for logging are provided in the framework. They are Java Util Logging, Log4J2, and Logback. Loggers are pre-configured for printing the output on the console or in the configured file.
3. Download the Source Code
You can download the full source code of this example here: Spring Boot Unit Testing Example