Using Spring Data JPA for integration tests without Spring Boot starter
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.
- Create
0002-data.sql
file to fill database with test data.
- 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 aPostgres
service
- Mount
Volumes
with init scripts andPostgres
toscript
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
- Add TAF dependencies to
build.gradle
.
Note: I addedJunit4
,Junit5
andTestNG
only for demo purposes, please choose only one, as for me — I’mTestNG
fan.
TAF setup
- Create
application.properties
file and fill in with credentials fromdocker-compose file
.
- Create
DatabaseConfig
class to configure database credentials
- Create
OrmConfig
class to configure Object Relational Mapping JPA configuration
- Create
RepositoryConfig
to configure Components ans JPA repositories dependency scanning.
- Create
Player
class to represent database entity
- Create interface
PlayerRepository
and extend in fromCrudRepository
and the magic will happen. How magic is happening described here
Integration test setup
- With
Junit4
- With
Junit5
- With
TestNG
- Viola! Happy Testing!
Source code can be found on GitHub: