📘 Premium Read: Access my best content on
Medium member-only articles
— deep dives into Java, Spring Boot, Microservices, backend architecture, interview preparation, career advice, and industry-standard best practices.
🎓 Top 15 Udemy Courses (80-90% Discount):
My Udemy Courses - Ramesh Fadatare
— All my Udemy courses are real-time and project oriented courses.
First, we write Integration tests using a local MySQL database, and then we will address the problem with Testcontainers as a solution.
SpringBoot provides excellent support for integration testing using @SpringBootTest annotation. We can use @SpringBootTest annotation to load the application context and test various components.
@SpringBootTest will bootstrap the full application context, which means we can @Autowire any bean that's picked up by component scanning into our test.
In this tutorial, we are going to use @SpringBootTest annotation for Integration testing.
YouTube Video
Tools and technologies used
Java 11+
Spring Boot
Spring Data JPA
MySQL
Lombok
JUnit 5 Framework
IntelliJ IDEA
Testcontainers
Docker
Maven
What is Integration Testing
As the name suggests, integration tests focus on integrating different layers of the application. That also means no mocking is involved.
Basically, we write integration tests for testing a feature that may involve interaction with multiple components.
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.
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())));
7. Run Integration Test
What is the problem with the Integration test that we have written?
A common problem when writing integration tests is the dependency on installed components (Ex: MySQL, RabbitMQ) where the integration tests are supposed to run.
In our case, our Integration tests depend on the MySQL database. Installing a specific version of the MySQL database in every machine where the integration tests are supposed to run takes a lot of time right.
Basically, our integration tests depend on external services (installing MySQL, Rabbit MQ, Redis, etc) to run the integration tests right then how to reduce this dependency - what will be the solution.
The solution is Testcontainers.
8. What is Testcontainers?
Testcontainers is a Java library that supports JUnit tests, providing lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container.
Using Testcontainers is fairly easy and it gives us the opportunity to create integration tests without the need for pre-installed components.
Using Testcontainers, we would always start with a clean database and our integration tests could run on any machine.
Testcontainer allows us to use Docker containers within our tests. As a result, we can write self-contained integration tests that depend on external resources.
9. Adding Testcontainers to Spring Boot Project
Open the pom.xml file and add the following Testcontainers dependencies:
Comments
Post a Comment
Leave Comment