- Spring Boot - Home
- Spring Boot - Introduction
- Spring Boot - Quick Start using CLI
- Spring Boot - Bootstrapping
- Spring Tool Suite
- Spring Boot - Tomcat Deployment
- Spring Boot - Build Systems
- Spring Boot - Code Structure
- Spring Boot - Beans & Dependency Injection
- Spring Boot - Runners
- Spring Boot - Starters
- Spring Boot - Application Properties
- Spring Boot - Configuration
- Spring Boot - Annotations
- Spring Boot - Logging
- Building RESTful Web Services
- Spring Boot - Exception Handling
- Spring Boot - Interceptor
- Spring Boot - Servlet Filter
- Spring Boot - Tomcat Port Number
- Spring Boot - Rest Template
- Spring Boot - File Handling
- Spring Boot - Service Components
- Spring Boot - Thymeleaf
- Consuming RESTful Web Services
- Spring Boot - CORS Support
- Spring Boot - Internationalization
- Spring Boot - Scheduling
- Spring Boot - Enabling HTTPS
- Spring Boot - Eureka Server
- Service Registration with Eureka
- Gateway Proxy Server and Routing
- Spring Cloud Configuration Server
- Spring Cloud Configuration Client
- Spring Boot - Actuator
- Spring Boot - Admin Server
- Spring Boot - Admin Client
- Spring Boot - Enabling Swagger2
- Spring Boot - Using SpringDoc OpenAPI
- Spring Boot - Creating Docker Image
- Tracing Micro Service Logs
- Spring Boot - Flyway Database
- Spring Boot - Sending Email
- Spring Boot - Hystrix
- Spring Boot - Web Socket
- Spring Boot - Batch Service
- Spring Boot - Apache Kafka
- Spring Boot - Twilio
- Spring Boot - Unit Testing
- Rest Controller Unit Testing
- Spring Boot - Database Handling
- Securing Web Applications
- Spring Boot - OAuth2 with JWT
- Spring Boot - Google Cloud Platform
- Spring Boot - Google OAuth2 Sign-In
Spring Boot Resources
Spring Boot - Rest Controller Unit Testing
Spring Boot provides an easy way to write a Unit Test for Rest Controller file. With the help of SpringJUnit4ClassRunner and MockMvc, we can create a web application context to write Unit Test for Rest Controller file.
Unit Tests should be written under the src/test/java directory and classpath resources for writing a test should be placed under the src/test/resources directory.
Example - Unit Testing a Rest Controller
For Writing a Unit Test, we need to add the Spring Boot Starter Test dependency in your build configuration file as shown below.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency>
Gradle users can add the following dependency in your build.gradle file.
testCompile('org.springframework.boot:spring-boot-starter-test')
Before writing a Test case, we should first build RESTful web services. For further information on building RESTful web services, please refer to the Building RESTful Web Services chapter.
Writing a Unit Test for REST Controller
In this section, let us see how to write a Unit Test for the REST Controller.
First, we need to create Abstract class file used to create web application context by using MockMvc and define the mapToJson() and mapFromJson() methods to convert the Java object into JSON string and convert the JSON string into Java object.
AbstractTest.java
package com.tutorialspoint.demo;
import java.io.IOException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
@SpringBootTest(classes = DemoApplication.class)
@WebAppConfiguration
public abstract class AbstractTest {
protected MockMvc mvc;
@Autowired
WebApplicationContext webApplicationContext;
protected void setUp() {
mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
protected String mapToJson(Object obj) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.writeValueAsString(obj);
}
protected <T> T mapFromJson(String json, Class<T> clazz)
throws JsonParseException, JsonMappingException, IOException {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(json, clazz);
}
}
Next, write a class file that extends the AbstractTest class and write a Unit Test for each method such GET, POST, PUT and DELETE.
The code for GET API Test case is given below. This API is to view the list of products.
@Test
public void getProductsList() throws Exception {
String uri = "/products";
MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.get(uri)
.accept(MediaType.APPLICATION_JSON_VALUE)).andReturn();
int status = mvcResult.getResponse().getStatus();
assertEquals(200, status);
String content = mvcResult.getResponse().getContentAsString();
Product[] productlist = super.mapFromJson(content, Product[].class);
assertTrue(productlist.length > 0);
}
The code for POST API test case is given below. This API is to create a product.
@Test
public void createProduct() throws Exception {
String uri = "/products";
Product product = new Product();
product.setId("3");
product.setName("Ginger");
String inputJson = super.mapToJson(product);
MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.post(uri)
.contentType(MediaType.APPLICATION_JSON_VALUE).content(inputJson)).andReturn();
int status = mvcResult.getResponse().getStatus();
assertEquals(201, status);
String content = mvcResult.getResponse().getContentAsString();
assertEquals(content, "Product is created successfully");
}
The code for PUT API Test case is given below. This API is to update the existing product.
@Test
public void updateProduct() throws Exception {
String uri = "/products/2";
Product product = new Product();
product.setName("Lemon");
String inputJson = super.mapToJson(product);
MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.put(uri)
.contentType(MediaType.APPLICATION_JSON_VALUE).content(inputJson)).andReturn();
int status = mvcResult.getResponse().getStatus();
assertEquals(200, status);
String content = mvcResult.getResponse().getContentAsString();
assertEquals(content, "Product is updated successsfully");
}
The code for Delete API Test case is given below. This API will delete the existing product.
@Test
public void deleteProduct() throws Exception {
String uri = "/products/2";
MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.delete(uri)).andReturn();
int status = mvcResult.getResponse().getStatus();
assertEquals(200, status);
String content = mvcResult.getResponse().getContentAsString();
assertEquals(content, "Product is deleted successsfully");
}
The full Controller Test class file is given below −
ProductServiceControllerTest.java
package com.tutorialspoint.demo;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import com.tutorialspoint.demo.model.Product;
public class ProductServiceControllerTest extends AbstractTest {
@Override
@BeforeEach
public void setUp() {
super.setUp();
}
@Test
public void getProductsList() throws Exception {
String uri = "/products";
MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.get(uri)
.accept(MediaType.APPLICATION_JSON_VALUE)).andReturn();
int status = mvcResult.getResponse().getStatus();
assertEquals(200, status);
String content = mvcResult.getResponse().getContentAsString();
Product[] productlist = super.mapFromJson(content, Product[].class);
assertTrue(productlist.length > 0);
}
@Test
public void createProduct() throws Exception {
String uri = "/products";
Product product = new Product();
product.setId("3");
product.setName("Ginger");
String inputJson = super.mapToJson(product);
MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.post(uri)
.contentType(MediaType.APPLICATION_JSON_VALUE)
.content(inputJson)).andReturn();
int status = mvcResult.getResponse().getStatus();
assertEquals(201, status);
String content = mvcResult.getResponse().getContentAsString();
assertEquals(content, "Product is created successfully");
}
@Test
public void updateProduct() throws Exception {
String uri = "/products/2";
Product product = new Product();
product.setName("Lemon");
String inputJson = super.mapToJson(product);
MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.put(uri)
.contentType(MediaType.APPLICATION_JSON_VALUE)
.content(inputJson)).andReturn();
int status = mvcResult.getResponse().getStatus();
assertEquals(200, status);
String content = mvcResult.getResponse().getContentAsString();
assertEquals(content, "Product is updated successsfully");
}
@Test
public void deleteProduct() throws Exception {
String uri = "/products/2";
MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.delete(uri)).andReturn();
int status = mvcResult.getResponse().getStatus();
assertEquals(200, status);
String content = mvcResult.getResponse().getContentAsString();
assertEquals(content, "Product is deleted successsfully");
}
}
The code for complete build configuration file Maven build pom.xml is given below −
pom.xml
<?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>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.tutorialspoint</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>21</java.version>
</properties>
<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>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Compilation and Execution
You can create an executable JAR file, and run the Spring Boot application by using the Maven or Gradle commands given below −
For Maven, you can use the command given below −
mvn clean install
Now, you can see the test results in console window.
[INFO] Scanning for projects... [INFO] [INFO] [1m----------------------< [0;36mcom.tutorialspoint:demo[0;1m >-----------------------[m [INFO] [1mBuilding demo 0.0.1-SNAPSHOT[m [INFO] from pom.xml [INFO] [1m--------------------------------[ war ]---------------------------------[m [INFO] [INFO] [1m--- [0;32mresources:3.3.1:resources[m [1m(default-resources)[m @ [36mdemo[0;1m ---[m [INFO] Copying 1 resource from src\main\resources to target\classes [INFO] Copying 8 resources from src\main\resources to target\classes [INFO] [INFO] [1m--- [0;32mcompiler:3.14.0:compile[m [1m(default-compile)[m @ [36mdemo[0;1m ---[m [INFO] Nothing to compile - all classes are up to date. [INFO] [INFO] [1m--- [0;32mresources:3.3.1:testResources[m [1m(default-testResources)[m @ [36mdemo[0;1m ---[m [INFO] skip non existing resourceDirectory D:\Projects\demo\src\test\resources [INFO] [INFO] [1m--- [0;32mcompiler:3.14.0:testCompile[m [1m(default-testCompile)[m @ [36mdemo[0;1m ---[m [INFO] Nothing to compile - all classes are up to date. [INFO] [INFO] [1m--- [0;32msurefire:3.5.4:test[m [1m(default-test)[m @ [36mdemo[0;1m ---[m [INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider [INFO] [INFO] ------------------------------------------------------- [INFO] T E S T S [INFO] ------------------------------------------------------- [INFO] Running com.tutorialspoint.demo.[1mDemoApplicationTests[m [2025-09-30T12:09:38Z] [org.springframework.test.context.support.AnnotationConfigContextLoaderUtils] [main] [83] [INFO ] Could not detect default configuration classes for test class [com.tutorialspoint.demo.DemoApplicationTests]: DemoApplicationTests does not declare any static, non-private, non-final, nested classes annotated with @Configuration. [2025-09-30T12:09:38Z] [org.springframework.boot.test.context.SpringBootTestContextBootstrapper] [main] [234] [INFO ] Found @SpringBootConfiguration com.tutorialspoint.demo.DemoApplication for test class com.tutorialspoint.demo.DemoApplicationTests . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v3.5.6) [2025-09-30T12:09:38Z] [org.springframework.boot.StartupInfoLogger] [main] [53] [INFO ] Starting DemoApplicationTests using Java 21.0.6 with PID 38544 (started by mahes in D:\Projects\demo) [2025-09-30T12:09:38Z] [org.springframework.boot.SpringApplication] [main] [652] [INFO ] No active profile set, falling back to 1 default profile: "default" [2025-09-30T12:09:40Z] [org.springframework.boot.autoconfigure.web.servlet.WelcomePageHandlerMapping] [main] [59] [INFO ] Adding welcome page template: index [2025-09-30T12:09:41Z] [org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver] [main] [60] [INFO ] Exposing 1 endpoint beneath base path '/actuator' [2025-09-30T12:09:41Z] [org.springframework.boot.StartupInfoLogger] [main] [59] [INFO ] Started DemoApplicationTests in 2.571 seconds (process running for 3.792) Mockito is currently self-attaching to enable the inline-mock-maker. This will no longer work in future releases of the JDK. Please add Mockito as an agent to your build as described in Mockito's documentation: https://javadoc.io/doc/org.mockito/mockito-core/latest/org.mockito/org/mockito/Mockito.html#0.3 WARNING: A Java agent has been loaded dynamically (C:\Users\mahes\.m2\repository\net\bytebuddy\byte-buddy-agent\1.17.7\byte-buddy-agent-1.17.7.jar) WARNING: If a serviceability tool is in use, please run with -XX:+EnableDynamicAgentLoading to hide this warning WARNING: If a serviceability tool is not in use, please run with -Djdk.instrument.traceUsage for more information WARNING: Dynamic loading of agents will be disallowed by default in a future release OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended [INFO] [1;32mTests run: [0;1;32m1[m, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 4.134 s -- in com.tutorialspoint.demo.[1mDemoApplicationTests[m [INFO] Running com.tutorialspoint.demo.[1mProductServiceControllerTest[m . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v3.5.6) [2025-09-30T12:09:42Z] [org.springframework.boot.StartupInfoLogger] [main] [53] [INFO ] Starting ProductServiceControllerTest using Java 21.0.6 with PID 38544 (started by mahes in D:\Projects\demo) [2025-09-30T12:09:42Z] [org.springframework.boot.SpringApplication] [main] [652] [INFO ] No active profile set, falling back to 1 default profile: "default" [2025-09-30T12:09:42Z] [org.springframework.boot.autoconfigure.web.servlet.WelcomePageHandlerMapping] [main] [59] [INFO ] Adding welcome page template: index [2025-09-30T12:09:42Z] [org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver] [main] [60] [INFO ] Exposing 1 endpoint beneath base path '/actuator' [2025-09-30T12:09:42Z] [org.springframework.boot.StartupInfoLogger] [main] [59] [INFO ] Started ProductServiceControllerTest in 0.472 seconds (process running for 5.203) [2025-09-30T12:09:42Z] [org.springframework.mock.web.MockServletContext] [main] [440] [INFO ] Initializing Spring TestDispatcherServlet '' [2025-09-30T12:09:42Z] [org.springframework.web.servlet.FrameworkServlet] [main] [532] [INFO ] Initializing Servlet '' [2025-09-30T12:09:42Z] [org.springframework.web.servlet.FrameworkServlet] [main] [554] [INFO ] Completed initialization in 1 ms Pre Handle method is Calling Post Handle method is Calling Request and Response is completed [2025-09-30T12:09:42Z] [org.springframework.mock.web.MockServletContext] [main] [440] [INFO ] Initializing Spring TestDispatcherServlet '' [2025-09-30T12:09:42Z] [org.springframework.web.servlet.FrameworkServlet] [main] [532] [INFO ] Initializing Servlet '' [2025-09-30T12:09:42Z] [org.springframework.web.servlet.FrameworkServlet] [main] [554] [INFO ] Completed initialization in 1 ms Pre Handle method is Calling Post Handle method is Calling Request and Response is completed [2025-09-30T12:09:42Z] [org.springframework.mock.web.MockServletContext] [main] [440] [INFO ] Initializing Spring TestDispatcherServlet '' [2025-09-30T12:09:42Z] [org.springframework.web.servlet.FrameworkServlet] [main] [532] [INFO ] Initializing Servlet '' [2025-09-30T12:09:42Z] [org.springframework.web.servlet.FrameworkServlet] [main] [554] [INFO ] Completed initialization in 1 ms Pre Handle method is Calling Post Handle method is Calling Request and Response is completed [2025-09-30T12:09:42Z] [org.springframework.mock.web.MockServletContext] [main] [440] [INFO ] Initializing Spring TestDispatcherServlet '' [2025-09-30T12:09:42Z] [org.springframework.web.servlet.FrameworkServlet] [main] [532] [INFO ] Initializing Servlet '' [2025-09-30T12:09:42Z] [org.springframework.web.servlet.FrameworkServlet] [main] [554] [INFO ] Completed initialization in 1 ms Pre Handle method is Calling Post Handle method is Calling Request and Response is completed [INFO] [1;32mTests run: [0;1;32m4[m, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.773 s -- in com.tutorialspoint.demo.[1mProductServiceControllerTest[m [INFO] [INFO] Results: [INFO] [INFO] [1;32mTests run: 5, Failures: 0, Errors: 0, Skipped: 0[m [INFO] [INFO] [INFO] [1m--- [0;32mwar:3.4.0:war[m [1m(default-war)[m @ [36mdemo[0;1m ---[m [INFO] Packaging webapp [INFO] Assembling webapp [demo] in [D:\Projects\demo\target\demo-0.0.1-SNAPSHOT] [INFO] Processing war project [INFO] Copying webapp resources [D:\Projects\demo\src\main\webapp] [INFO] Building war: D:\Projects\demo\target\demo-0.0.1-SNAPSHOT.war [INFO] [INFO] [1m--- [0;32mspring-boot:3.5.6:repackage[m [1m(repackage)[m @ [36mdemo[0;1m ---[m [INFO] Replacing main artifact D:\Projects\demo\target\demo-0.0.1-SNAPSHOT.war with repackaged archive, adding nested dependencies in BOOT-INF/. [INFO] The original artifact has been renamed to D:\Projects\demo\target\demo-0.0.1-SNAPSHOT.war.original [INFO] [INFO] [1m--- [0;32minstall:3.1.4:install[m [1m(default-install)[m @ [36mdemo[0;1m ---[m [INFO] Installing D:\Projects\demo\pom.xml to C:\Users\mahes\.m2\repository\com\tutorialspoint\demo\0.0.1-SNAPSHOT\demo-0.0.1-SNAPSHOT.pom [INFO] Installing D:\Projects\demo\target\demo-0.0.1-SNAPSHOT.war to C:\Users\mahes\.m2\repository\com\tutorialspoint\demo\0.0.1-SNAPSHOT\demo-0.0.1-SNAPSHOT.war [INFO] [1m------------------------------------------------------------------------[m [INFO] [1;32mBUILD SUCCESS[m [INFO] [1m------------------------------------------------------------------------[m [INFO] Total time: 10.730 s [INFO] Finished at: 2025-09-30T12:09:46+05:30 [INFO] [1m------------------------------------------------------------------------[m