Using Spring Data JPA for integration tests without Spring Boot starter

Pavel Klindziuk
Dandelion Tutorials
3 min readDec 10, 2023
Spring Boot Data JPA Starter vs Spring Data Japa

Integration testing with database usage
A database is a central part of most software, and every application that relies on a database for data persistence should include an extensive test suite. These tests should verify the correctness of the queries and also confirm that its integration with the software is working as intended.

We definitely need to get data from database to verify it, so how we can get it? For me answer is quite simple — Spring Data

What is Spring Data?

Spring Data is an umbrella project having number of sub-projects or modules all aimed towards providing uniform abstractions and uniform utility methods for the Data Access Layer in an application and support wide range of databases.
Implementing a data access service for Test Automation Framework(TAF) be quite cumbersome. Too much boilerplate code has to be written to execute the simplest queries. Add things like pagination, auditing, and other often-needed options, and you end up lost.
Spring Data aims to significantly improve the implementation of data access layers by reducing the effort to the amount that’s actually needed. You write your repository interfaces using any number of techniques, and Spring will wire it up for you automatically. You can even use custom finders or query by example and Spring will write the query for you!
The fastest and easiest way to get this magic functionality — use Spring Boot Starter

What is Spring Boot Starter?
Dependency management is a critical aspects of any complex project. And doing this manually is less than ideal; the more time you spent on it the less time you have on the other important aspects of the project.
Spring Boot starters were built to address exactly this problem. Starter POMs are a set of convenient dependency descriptors that you can include in your application. You get a one-stop-shop for all the Spring and related technology that you need, without having to hunt through sample code and copy-paste loads of dependency descriptors.
But…

Why should not we use Spring Boot Starter for tests?
Due to its opinionated style, when there is one tried and tested way to develop an application, it takes much control out of the our hands.
Spring Boot starters installs many additional dependencies (that often go unused) which increases the application artifact size, loading time, dependency resolution conflicts and so on.
So, why do we need bring a truck to move some simple box with books?

Demo TAF

In order to get better acquainted with these technologies, let’s create simple Test Automation Framework to retrieve and verify EPL Football players data from database.

Prerequisites

  • Install Docker
  • Install JDK 17
  • Make a cup of coffee

Postgres DB Setup via Docker

  • Create 0001-schema.sql file to create database table.
0001-schema.sql
  • Create 0002-data.sql file to fill database with test data.
0002-data.sql
  • Put 0001-schema.sql and `0002-data.sql scripts into.script/sql directory or define any other path if you wish.
  • Create docker-compose.yml file with a Postgres service
docker-compose.yml
  • Mount Volumes with init scripts and Postgres to script folder path.
    volumes:
    - ./script/sql/0001-schema.sql:/docker-entrypoint-initdb.d/0001-schema.sql
    - ./script/sql/0002-data.sql:/docker-entrypoint-initdb.d/0002-data.sql
  • Start Postgres service via docker compose
    docker-compose -f docker-compose.yml up

Dependencies setup

  • Create Gradle project
  • Add database interaction dependencies to build.gradle
build.gradle
  • Add TAF dependencies to build.gradle .
    Note: I added Junit4 , Junit5 and TestNG only for demo purposes, please choose only one, as for me — I’m TestNG fan.
build.gradle

TAF setup

  • Create application.properties file and fill in with credentials from docker-compose file.
application.properties
  • Create DatabaseConfig class to configure database credentials
DatabaseConfig.java
  • Create OrmConfig class to configure Object Relational Mapping JPA configuration
OrmConfig.java
  • Create RepositoryConfig to configure Components ans JPA repositories dependency scanning.
RepositoryConfig.java
  • Create Player class to represent database entity
Player.java
  • Create interface PlayerRepository and extend in from CrudRepository
    and the magic will happen. How magic is happening described here
PlayerRepository.java

Integration test setup

  • With Junit4
Junit4PlayerTest.java
  • With Junit5
Junit5PlayerTest.java
  • With TestNG
TestNGPlayerTest.java
  • Viola! Happy Testing!

Source code can be found on GitHub:

--

--