How to test JPA Repository Spring Boot

The Spring Boot JPA Repository class allows you to retrieve data from a database table.The JPA Repository is used to test database CRUD operations like insert, update, delete, and select. In the spring boot JPA Repository test cases, the database connection and all database table CRUD operations on a table will be tested. It helps in the identification of database, database connection, and ORM frameworks such as hibernate issues. The JPA Repository test cases will identify errors with one-to-one, one-to-many, many-to-one, and many-to-many hibernate mappings. It also helps in the diagnosis of issues with hibernate’s lazy binding and early binding.

Spring Boot supports a wide range of test frameworks, including JUnit, Jupiter, TestNG, Mockito, and others, to create test cases. The spring boot JPA Repository test case classes are created using the @SpringBootTest annotation. Each test method is created using the annotation @Test. When spring boot runs the test, it runs all of the classes marked with the annotation @SpringBootTest and all of the methods marked with the annotation @Test. The test frameworks will compile the test results and present them in a summary format, including total test cases, failed test cases, error test cases, and skipped test cases.



Repository Class

The following is an example of a typical Spring Boot repository class. The jpa repository interface class will be created as an extension of the JpaRepository interface. The template will include an entity class for the JpaRepository interface. The JPA Repository class will be executed for the database table configured in the Entity class. The data type of the primary key column is indicated by the Long value in the template annotation.

package com.yawintutor.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.yawintutor.model.Student;

public interface StudentRepository extends JpaRepository<Student, Long> {

}


Repository Test Class

The repository test class should be annotated with @SpringBootTest, and the test method should be annotated with @Test. To autowire the repository class that has to be tested, use the @Autowired annotation. In the src/test/java subdirectory, write the jpa test class for spring boot. In the example below, an entity class named Student is used.

The student table has three columns: ID, name, and age. The primary key inserts an auto-generated integer value in the id column. The assertTrue method checks the results of database CRUD operations like insert, update, delete, and select. The student object with sample data is inserted first. The database has been updated with the new name. Finally, the student’s database object is deleted.

package com.yawintutor.repository;

import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.Optional;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import com.yawintutor.model.Student;

@SpringBootTest
public class StudentRepositoryTest {

	@Autowired
	StudentRepository repository;

	@Test
	public void studentRepositoryTest() {
		Student student = new Student();
		student.setName("Student1");
		student.setAge(15);

		// insert
		student = repository.save(student);
		Student st = repository.findById(student.getId()).get();
		System.out.println(st.getId() + " " + st.getName() + " " + st.getAge());
		assertTrue(student.getId() == st.getId());

		// update
		student.setName("student2");
		student = repository.save(student);
		st = repository.findById(student.getId()).get();
		System.out.println(st.getId() + " " + st.getName() + " " + st.getAge());
		assertTrue(student.getName().equals(st.getName()));

		// delete
		repository.delete(student);
		Optional<Student> stOpt = repository.findById(student.getId());
		assertTrue(stOpt.isEmpty());

	}

}


Entity Class

The following is the entity class for the student database table. The student table has three columns: ID, name, and age. In the entity class, the columns will have a corresponding mapping. The student entity class has three member variables: id, name, and age.

package com.yawintutor.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Student {
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Id
	private long id;
	private String name;
	private int age;

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
	}

}


application.properties

As shown below, database configurations are added to the application properties file. The database credentials are contained in the url, username, and password. The mysql database is comprised of the driver class and dialect configurations. The last two properties for hibernate configurations.

spring.datasource.url=jdbc:mysql://localhost/testdb
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update


Pom.xml file

As stated below, the maven pom xml file is added. The database and spring boot jpa repository dependencies should be included to the pom.xml file.

<?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>2.6.3</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.yawintutor</groupId>
	<artifactId>SpringBootDatabase</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>SpringBootDatabase</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>11</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>com.microsoft.sqlserver</groupId>
			<artifactId>mssql-jdbc</artifactId>
			<scope>runtime</scope>
		</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>
			</plugin>
		</plugins>
	</build>

</project>


Main Method

The below code shows the default spring boot application main class and main method.

package com.yawintutor;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootDatabaseApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringBootDatabaseApplication.class, args);
	}

}


How to Run

The following logs will be displayed in the console window if you run the spring boot application test cases.

2022-01-28 07:58:58.088  INFO 90277 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2022-01-28 07:58:58.457  INFO 90277 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2022-01-28 07:58:58.473  INFO 90277 --- [           main] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
2022-01-28 07:58:59.006  INFO 90277 --- [           main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2022-01-28 07:58:59.013  INFO 90277 --- [           main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2022-01-28 07:58:59.404  WARN 90277 --- [           main] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2022-01-28 07:58:59.827  INFO 90277 --- [           main] c.y.repository.StudentRepositoryTest     : Started StudentRepositoryTest in 3.584 seconds (JVM running for 4.487)
Hibernate: select next_val as id_val from hibernate_sequence for update
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: insert into student (age, name, id) values (?, ?, ?)
Hibernate: select student0_.id as id1_0_0_, student0_.age as age2_0_0_, student0_.name as name3_0_0_ from student student0_ where student0_.id=?
11 Student1 15
Hibernate: select student0_.id as id1_0_0_, student0_.age as age2_0_0_, student0_.name as name3_0_0_ from student student0_ where student0_.id=?
Hibernate: update student set age=?, name=? where id=?
Hibernate: select student0_.id as id1_0_0_, student0_.age as age2_0_0_, student0_.name as name3_0_0_ from student student0_ where student0_.id=?
11 student2 15
Hibernate: select student0_.id as id1_0_0_, student0_.age as age2_0_0_, student0_.name as name3_0_0_ from student student0_ where student0_.id=?
Hibernate: delete from student where id=?
Hibernate: select student0_.id as id1_0_0_, student0_.age as age2_0_0_, student0_.name as name3_0_0_ from student student0_ where student0_.id=?
2022-01-28 07:59:00.044  INFO 90277 --- [ionShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2022-01-28 07:59:00.045  INFO 90277 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2022-01-28 07:59:00.055  INFO 90277 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.


Leave a Reply

Your email address will not be published. Required fields are marked *