π 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.
▶️ Subscribe to My YouTube Channel (176K+ subscribers): Java Guides on YouTube
▶️ For AI, ChatGPT, Web, Tech, and Generative AI, subscribe to another channel: Ramesh Fadatare on YouTube
Sometimes we might want to test the persistence layer components of our application, which doesn’t require the loading of many components like controllers, security configuration, and so on.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
Overview of Spring Boot Starter Test Dependency
- Spring-specific dependencies
- Dependencies for auto-configuration
- Set of testing libraries - JUnit, Mockito, Hamcrest, AssertJ, JSONassert, and JsonPath.
@DataJpaTest Annotation Overview
To test Spring Data JPA repositories or any other JPA-related components for that matter, Spring Boot provides the @DataJpaTest annotation. We can just add it to our unit test and it will set up a Spring application context:
@ExtendWith(SpringExtension.class) @DataJpaTest class UserEntityRepositoryTest { @Autowired private DataSource dataSource; @Autowired private JdbcTemplate jdbcTemplate; @Autowired private EntityManager entityManager; @Autowired private UserRepository userRepository; @Test void injectedComponentsAreNotNull(){ assertThat(dataSource).isNotNull(); assertThat(jdbcTemplate).isNotNull(); assertThat(entityManager).isNotNull(); assertThat(userRepository).isNotNull(); } }
1. Tools and Technologies Used
- Spring Boot - 3+
- JDK - 17 or later
- Spring Framework - 6
- H2
- Maven - 3+
- IDE - IntelliJ IDEA
2. Creating and Importing a Project
Use the below details in the Spring boot creation:
Project Name: spring-boot-testing
Project Type: Maven
Choose dependencies: Spring Data JPA, H2 database, Lombok
Package name: net.javaguides.springboot
3. Maven Dependencies
Here is the complete pom.xml for your reference:
<?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.0.4</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>net.javaguides</groupId> <artifactId>spring-boot-testing</artifactId> <version>0.0.1-SNAPSHOT</version> <name>spring-boot-testing</name> <description>Spring boot unit testing and integration testing</description> <properties> <java.version>17</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project>
4. Create JPA Entity - Employee.java
package net.javaguides.springboot.model; import lombok.*; import jakarta.persistence.*; @Setter @Getter @AllArgsConstructor @NoArgsConstructor @Builder @Entity @Table(name = "employees") public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; @Column(name = "first_name", nullable = false) private String firstName; @Column(name = "last_name", nullable = false) private String lastName; @Column(nullable = false) private String email; }
5. Create Spring Data JPA Repository
The next thing we’re gonna do is to create a repository to access an Employee's data from the database.
The JpaRepository interface defines methods for all the CRUD operations on the entity, and a default implementation of the JpaRepository called SimpleJpaRepository.
Let's create a repository package inside a base package "net.javaguides.springdatarest".
Within the repository package, create an EmployeeRepository interface with the following content:package net.javaguides.springboot.repository; import net.javaguides.springboot.model.Employee; import org.springframework.data.jpa.repository.JpaRepository; import java.util.Optional; public interface EmployeeRepository extends JpaRepository<Employee, Long> { }
The next thing we’re gonna do is to create a repository to access an Employee's data from the database.
The JpaRepository interface defines methods for all the CRUD operations on the entity, and a default implementation of the JpaRepository called SimpleJpaRepository.
package net.javaguides.springboot.repository; import net.javaguides.springboot.model.Employee; import org.springframework.data.jpa.repository.JpaRepository; import java.util.Optional; public interface EmployeeRepository extends JpaRepository<Employee, Long> { }
6. JUnit Tests for Spring Data JPA Repository
Spring Boot provides the @DataJpaTest annotation to test the persistence layer components that will autoconfigure in-memory embedded databases and scan for @Entity classes and Spring Data JPA repositories.
The @DataJpaTest annotation doesn’t load other Spring beans (@Components, @Controller, @Service, and annotated beans) into ApplicationContext.
Head over to the test package. Let's create a repository package inside a base package "test.net.javaguides.springboot".
Within the repository package, create an EmployeeRepositoryTests class with the following content:package net.javaguides.springboot.repository; import net.javaguides.springboot.model.Employee; import static org.assertj.core.api.Assertions.assertThat; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import java.util.List; import java.util.Optional; @DataJpaTest public class EmployeeRepositoryTests { @Autowired private EmployeeRepository employeeRepository; private Employee employee; @BeforeEach public void setup(){ employee = Employee.builder() .firstName("Ramesh") .lastName("Fadatare") .email("ramesh@gmail,com") .build(); } // JUnit test for save employee operation //@DisplayName("JUnit test for save employee operation") @Test public void givenEmployeeObject_whenSave_thenReturnSavedEmployee(){ //given - precondition or setup Employee employee = Employee.builder() .firstName("Ramesh") .lastName("Ramesh") .email("ramesh@gmail,com") .build(); // when - action or the behaviour that we are going test Employee savedEmployee = employeeRepository.save(employee); // then - verify the output assertThat(savedEmployee).isNotNull(); assertThat(savedEmployee.getId()).isGreaterThan(0); } // JUnit test for get all employees operation @DisplayName("JUnit test for get all employees operation") @Test public void givenEmployeesList_whenFindAll_thenEmployeesList(){ // given - precondition or setup Employee employee1 = Employee.builder() .firstName("John") .lastName("Cena") .email("cena@gmail,com") .build(); employeeRepository.save(employee); employeeRepository.save(employee1); // when - action or the behaviour that we are going test List<Employee> employeeList = employeeRepository.findAll(); // then - verify the output assertThat(employeeList).isNotNull(); assertThat(employeeList.size()).isEqualTo(2); } // JUnit test for get employee by id operation @DisplayName("JUnit test for get employee by id operation") @Test public void givenEmployeeObject_whenFindById_thenReturnEmployeeObject(){ employeeRepository.save(employee); // when - action or the behaviour that we are going test Employee employeeDB = employeeRepository.findById(employee.getId()).get(); // then - verify the output assertThat(employeeDB).isNotNull(); } // JUnit test for update employee operation @DisplayName("JUnit test for update employee operation") @Test public void givenEmployeeObject_whenUpdateEmployee_thenReturnUpdatedEmployee(){ employeeRepository.save(employee); // when - action or the behaviour that we are going test Employee savedEmployee = employeeRepository.findById(employee.getId()).get(); savedEmployee.setEmail("ram@gmail.com"); savedEmployee.setFirstName("Ram"); Employee updatedEmployee = employeeRepository.save(savedEmployee); // then - verify the output assertThat(updatedEmployee.getEmail()).isEqualTo("ram@gmail.com"); assertThat(updatedEmployee.getFirstName()).isEqualTo("Ram"); } // JUnit test for delete employee operation @DisplayName("JUnit test for delete employee operation") @Test public void givenEmployeeObject_whenDelete_thenRemoveEmployee(){ employeeRepository.save(employee); // when - action or the behaviour that we are going test employeeRepository.deleteById(employee.getId()); Optional<Employee> employeeOptional = employeeRepository.findById(employee.getId()); // then - verify the output assertThat(employeeOptional).isEmpty(); } }
Note that we are using the assertThat() method from the AssertJ library for assertions.
Let's understand the above JUnit tests one by one.
We have used @BeforeEach annotation to signal that the annotated method should be executed before each @Test method in the current test class:
@BeforeEach public void setup(){ employee = Employee.builder() .firstName("Ramesh") .lastName("Fadatare") .email("ramesh@gmail,com") .build(); }
JUnit test to save employee operation:
// JUnit test for save employee operation //@DisplayName("JUnit test for save employee operation") @Test public void givenEmployeeObject_whenSave_thenReturnSavedEmployee(){ //given - precondition or setup Employee employee = Employee.builder() .firstName("Ramesh") .lastName("Ramesh") .email("ramesh@gmail,com") .build(); // when - action or the behaviour that we are going test Employee savedEmployee = employeeRepository.save(employee); // then - verify the output assertThat(savedEmployee).isNotNull(); assertThat(savedEmployee.getId()).isGreaterThan(0); }
JUnit test to get all employees operation// JUnit test for get all employees operation @DisplayName("JUnit test for get all employees operation") @Test public void givenEmployeesList_whenFindAll_thenEmployeesList(){ // given - precondition or setup Employee employee1 = Employee.builder() .firstName("John") .lastName("Cena") .email("cena@gmail,com") .build(); employeeRepository.save(employee); employeeRepository.save(employee1); // when - action or the behaviour that we are going test List<Employee> employeeList = employeeRepository.findAll(); // then - verify the output assertThat(employeeList).isNotNull(); assertThat(employeeList.size()).isEqualTo(2); }
JUnit test to get single employee by id operation
// JUnit test for get employee by id operation @DisplayName("JUnit test for get employee by id operation") @Test public void givenEmployeeObject_whenFindById_thenReturnEmployeeObject(){ employeeRepository.save(employee); // when - action or the behaviour that we are going test Employee employeeDB = employeeRepository.findById(employee.getId()).get(); // then - verify the output assertThat(employeeDB).isNotNull(); }
JUnit test to update employee operation
// JUnit test for update employee operation @DisplayName("JUnit test for update employee operation") @Test public void givenEmployeeObject_whenUpdateEmployee_thenReturnUpdatedEmployee(){ employeeRepository.save(employee); // when - action or the behaviour that we are going test Employee savedEmployee = employeeRepository.findById(employee.getId()).get(); savedEmployee.setEmail("ram@gmail.com"); savedEmployee.setFirstName("Ram"); Employee updatedEmployee = employeeRepository.save(savedEmployee); // then - verify the output assertThat(updatedEmployee.getEmail()).isEqualTo("ram@gmail.com"); assertThat(updatedEmployee.getFirstName()).isEqualTo("Ram"); }
JUnit test for delete employee operation// JUnit test for delete employee operation @DisplayName("JUnit test for delete employee operation") @Test public void givenEmployeeObject_whenDelete_thenRemoveEmployee(){ employeeRepository.save(employee); // when - action or the behaviour that we are going test employeeRepository.deleteById(employee.getId()); Optional<Employee> employeeOptional = employeeRepository.findById(employee.getId()); // then - verify the output assertThat(employeeOptional).isEmpty(); } }
package net.javaguides.springboot.repository; import net.javaguides.springboot.model.Employee; import static org.assertj.core.api.Assertions.assertThat; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import java.util.List; import java.util.Optional; @DataJpaTest public class EmployeeRepositoryTests { @Autowired private EmployeeRepository employeeRepository; private Employee employee; @BeforeEach public void setup(){ employee = Employee.builder() .firstName("Ramesh") .lastName("Fadatare") .email("ramesh@gmail,com") .build(); } // JUnit test for save employee operation //@DisplayName("JUnit test for save employee operation") @Test public void givenEmployeeObject_whenSave_thenReturnSavedEmployee(){ //given - precondition or setup Employee employee = Employee.builder() .firstName("Ramesh") .lastName("Ramesh") .email("ramesh@gmail,com") .build(); // when - action or the behaviour that we are going test Employee savedEmployee = employeeRepository.save(employee); // then - verify the output assertThat(savedEmployee).isNotNull(); assertThat(savedEmployee.getId()).isGreaterThan(0); } // JUnit test for get all employees operation @DisplayName("JUnit test for get all employees operation") @Test public void givenEmployeesList_whenFindAll_thenEmployeesList(){ // given - precondition or setup Employee employee1 = Employee.builder() .firstName("John") .lastName("Cena") .email("cena@gmail,com") .build(); employeeRepository.save(employee); employeeRepository.save(employee1); // when - action or the behaviour that we are going test List<Employee> employeeList = employeeRepository.findAll(); // then - verify the output assertThat(employeeList).isNotNull(); assertThat(employeeList.size()).isEqualTo(2); } // JUnit test for get employee by id operation @DisplayName("JUnit test for get employee by id operation") @Test public void givenEmployeeObject_whenFindById_thenReturnEmployeeObject(){ employeeRepository.save(employee); // when - action or the behaviour that we are going test Employee employeeDB = employeeRepository.findById(employee.getId()).get(); // then - verify the output assertThat(employeeDB).isNotNull(); } // JUnit test for update employee operation @DisplayName("JUnit test for update employee operation") @Test public void givenEmployeeObject_whenUpdateEmployee_thenReturnUpdatedEmployee(){ employeeRepository.save(employee); // when - action or the behaviour that we are going test Employee savedEmployee = employeeRepository.findById(employee.getId()).get(); savedEmployee.setEmail("ram@gmail.com"); savedEmployee.setFirstName("Ram"); Employee updatedEmployee = employeeRepository.save(savedEmployee); // then - verify the output assertThat(updatedEmployee.getEmail()).isEqualTo("ram@gmail.com"); assertThat(updatedEmployee.getFirstName()).isEqualTo("Ram"); } // JUnit test for delete employee operation @DisplayName("JUnit test for delete employee operation") @Test public void givenEmployeeObject_whenDelete_thenRemoveEmployee(){ employeeRepository.save(employee); // when - action or the behaviour that we are going test employeeRepository.deleteById(employee.getId()); Optional<Employee> employeeOptional = employeeRepository.findById(employee.getId()); // then - verify the output assertThat(employeeOptional).isEmpty(); } }
@BeforeEach public void setup(){ employee = Employee.builder() .firstName("Ramesh") .lastName("Fadatare") .email("ramesh@gmail,com") .build(); }
// JUnit test for save employee operation //@DisplayName("JUnit test for save employee operation") @Test public void givenEmployeeObject_whenSave_thenReturnSavedEmployee(){ //given - precondition or setup Employee employee = Employee.builder() .firstName("Ramesh") .lastName("Ramesh") .email("ramesh@gmail,com") .build(); // when - action or the behaviour that we are going test Employee savedEmployee = employeeRepository.save(employee); // then - verify the output assertThat(savedEmployee).isNotNull(); assertThat(savedEmployee.getId()).isGreaterThan(0); }
// JUnit test for get all employees operation @DisplayName("JUnit test for get all employees operation") @Test public void givenEmployeesList_whenFindAll_thenEmployeesList(){ // given - precondition or setup Employee employee1 = Employee.builder() .firstName("John") .lastName("Cena") .email("cena@gmail,com") .build(); employeeRepository.save(employee); employeeRepository.save(employee1); // when - action or the behaviour that we are going test List<Employee> employeeList = employeeRepository.findAll(); // then - verify the output assertThat(employeeList).isNotNull(); assertThat(employeeList.size()).isEqualTo(2); }
// JUnit test for get employee by id operation @DisplayName("JUnit test for get employee by id operation") @Test public void givenEmployeeObject_whenFindById_thenReturnEmployeeObject(){ employeeRepository.save(employee); // when - action or the behaviour that we are going test Employee employeeDB = employeeRepository.findById(employee.getId()).get(); // then - verify the output assertThat(employeeDB).isNotNull(); }
// JUnit test for update employee operation @DisplayName("JUnit test for update employee operation") @Test public void givenEmployeeObject_whenUpdateEmployee_thenReturnUpdatedEmployee(){ employeeRepository.save(employee); // when - action or the behaviour that we are going test Employee savedEmployee = employeeRepository.findById(employee.getId()).get(); savedEmployee.setEmail("ram@gmail.com"); savedEmployee.setFirstName("Ram"); Employee updatedEmployee = employeeRepository.save(savedEmployee); // then - verify the output assertThat(updatedEmployee.getEmail()).isEqualTo("ram@gmail.com"); assertThat(updatedEmployee.getFirstName()).isEqualTo("Ram"); }
// JUnit test for delete employee operation @DisplayName("JUnit test for delete employee operation") @Test public void givenEmployeeObject_whenDelete_thenRemoveEmployee(){ employeeRepository.save(employee); // when - action or the behaviour that we are going test employeeRepository.deleteById(employee.getId()); Optional<Employee> employeeOptional = employeeRepository.findById(employee.getId()); // then - verify the output assertThat(employeeOptional).isEmpty(); } }
7. Running JUnit Tests
The output of the tests is shown below screenshot:
Thanks for the quick tut.!
ReplyDeletecould you share the repo?
ReplyDelete