@SpringBootTest Spring Boot Example

In this quick article, we will learn how to use @SpringBootTest annotation to perform Integration testing in Spring boot applications.

Spring Boot provides @SpringBootTest annotation for Integration testing. 

In this tutorial, we will use the MySQL database for Integration testing 

Let's first take a look at the overview of @SpringBootTest annotation.

@SpringBootTest Annotation

Spring Boot provides @SpringBootTest annotation for Integration testing. This annotation creates an application context and loads the full application context.

@SpringBootTest will bootstrap the full application context, which means we can @Autowire any bean that's picked up by component scanning into our test.
It starts the embedded server, creates a web environment, and then enables @Test methods to do integration testing.

By default, @SpringBootTest  does not start a server. We need to add the attribute webEnvironment to further refine how your tests run. It has several options: 
  • MOCK(Default): Loads a web ApplicationContext and provides a mock web environment.
  • RANDOM_PORT: Loads a WebServerApplicationContext and provides a real web environment. The embedded server is started and listened to a random port. This is the one that should be used for the integration test.
  • DEFINED_PORT: Loads a WebServerApplicationContext and provides a real web environment. NONE: Loads an ApplicationContext by using SpringApplication but does not provide any web environment.

So basically, the @SpringBootTest annotation tells Spring Boot to look for the main configuration class (one with @SpringBootApplication, for instance) and use that to start a Spring application context.

@SpringBootTest Annotation Example

Create Spring Boot Application

Using spring initialize, create a Spring Boot project and add the following dependencies:
  • Spring Web
  • Spring Data JPA
  • Lombok
  • MySQL Driver
Generate the Spring boot project as a zip file, extract it, and import it into IntelliJ IDEA.

Configure MySQL database

Let's use the MySQL database to store and retrieve the data in this example and we gonna use Hibernate properties to create and drop tables.

Open the application.properties file and add the following configuration to it:
spring.datasource.url=jdbc:mysql://localhost:3306/demo?useSSL=false
spring.datasource.username=root
spring.datasource.password=Mysql@123

spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialect

spring.jpa.hibernate.ddl-auto = create-drop
Make sure that you will create a demo database before running the Spring boot application.

Create JPA Entity

Let's create a Student JPA entity with following content to it: 
package net.javaguides.spirngboot.entity;

import lombok.*;

import jakarta.persistence.*;

@Setter
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "students")
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;
    private String email;
}

Create Spring Data JPA Repository

Let's create StudentRepository which extends the JpaRepository interface:
package net.javaguides.spirngboot.repository;

import net.javaguides.spirngboot.entity.Student;
import org.springframework.data.jpa.repository.JpaRepository;

public interface StudentRepository extends JpaRepository<Student, Long> {
}

Create Spring Boot REST Controller

Let's create StudentController class and add these couple of REST endpoints:
package net.javaguides.spirngboot.controller;

import net.javaguides.spirngboot.entity.Student;
import net.javaguides.spirngboot.repository.StudentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/students")
public class StudentController {

    @Autowired
    private StudentRepository studentRepository;

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public Student createStudent(@RequestBody Student student){
        return studentRepository.save(student);
    }

    @GetMapping
    public List<Student> getAllStudents(){
        return studentRepository.findAll();
    }
}

Create Integration Tests with MySQL database

Now, let's create an Integration JUnit test for GET ALL Students REST API:
package net.javaguides.spirngboot;

import net.javaguides.spirngboot.entity.Student;
import net.javaguides.spirngboot.repository.StudentRepository;
import org.hamcrest.CoreMatchers;
import org.junit.jupiter.api.Test;
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.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;

import java.util.List;

@SpringBootTest
@AutoConfigureMockMvc
class SpringbootTestcontainersDemoApplicationTests {

	@Autowired
	private StudentRepository studentRepository;

	@Autowired
	private MockMvc mockMvc;

	// given/when/then format - BDD style
	@Test
	public void givenStudents_whenGetAllStudents_thenListOfStudents() throws Exception {
		// given - setup or precondition
		List<Student> students =
				List.of(Student.builder().firstName("Ramesh").lastName("faadatare").email("ramesh@gmail.com").build(),
				Student.builder().firstName("tony").lastName("stark").email("tony@gmail.com").build());
		studentRepository.saveAll(students);

		// when - action
		ResultActions response = mockMvc.perform(MockMvcRequestBuilders.get("/api/students"));

		// then - verify the output
		response.andExpect(MockMvcResultMatchers.status().isOk());
		response.andExpect(MockMvcResultMatchers.jsonPath("$.size()", CoreMatchers.is(students.size())));
	}

}
Let's understand the above code.

We are using @SpringBootTest annotation to load the application context and test various components.

MockMvc provides support for Spring MVC testing. It encapsulates all web application beans and makes them available for testing. @AutoConfigureMockMvc annotation that can be applied to a test class to enable and configure auto-configuration of MockMvc.
@Autowired
private MockMvc mockMvc;
The MockMvc.perform() method will call a GET request method, which returns the ResultActions.
ResultActions response = mockMvc.perform(MockMvcRequestBuilders.get("/api/students"));
Using this result, we can have assertion expectations about the response, like its content, HTTP status, or header. 

The andExpect() will expect the provided argument. In our case, we're expecting HTTP status code and the size of the JSON array in the response:
// then - verify the output
response.andExpect(MockMvcResultMatchers.status().isOk());
response.andExpect(MockMvcResultMatchers.jsonPath("$.size()", CoreMatchers.is(students.size())));

Run Integration Test

Conclusion

In this tutorial, we have seen the overview of @SpringBootTest annotation and we have also created a simple example to demonstrate the usage of @SpringBootTest annotation in the Spring boot application.

Related Spring Boot Testing Tutorials and Guides

Comments