In our previous tutorial, we implemented the soft delete functionality for the user entity and wrote a JUnit test to test the persistent layer. In this tutorial, we are gonna understand how the @DataJpaTest can be used for various scenarios to test the persistence layer.
Introduction
@DataJpaTest focuses only on JPA components. Using this annotation will disable full auto-configuration and instead apply only configuration relevant to JPA tests.
By default,
- It scans for
@Entityclasses and configures Spring Data JPA repositories. If an embedded database is available on the classpath, it configures one as well replacing any explicit or usually auto-configuredDataSource. - Tests annotated with
@DataJpaTestare transactional and roll back at the end of each test. If you want to override these settings, then use the@AutoConfigureTestDatabaseannotation. - SQL queries are logged by setting the
spring.jpa.show-sqlproperty totrue. You can disable this using theshowSqlattribute.
If you are looking to load your full application configuration, but use an embedded database, you should consider @SpringBootTest combined with @AutoConfigureTestDatabase rather than this annotation.
When using JUnit 4, this annotation should be used in combination with @RunWith(SpringRunner.class).
Test with Embedded In-memory Database
As described earlier, @DataJpaTest will try to configure an embedded database that is available in the classpath by default. This means we need to include the dependency of any one of the embedded databases in our pom.xml. Otherwise, we will end up with the following error:
Caused by: java.lang.IllegalStateException: Failed to replace DataSource with an embedded database for tests. If you want an embedded database please put a supported one on the classpath or tune the replace attribute of @AutoConfigureTestDatabase.
Once we add an embedded database dependency like h2 in our pom.xml, then we can use the @DataJpaTest annotation to run the tests on the embedded in-memory h2 database.
@DataJpaTest
class UserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Autowired
private RoleRepository roleRepository;
@Test
void testSoftDelete() {
// Add a new user
User user = new User();
user.setDisplayName("Chinna");
user.setEmail("[email protected]");
// Add a role to the user
Role adminRole = roleRepository.findByName(Role.ROLE_ADMIN);
user.addRole(roleRepository.findByName(Role.ROLE_USER));
user.addRole(adminRole);
user = userRepository.saveAndFlush(user);
assertEquals(2, user.getRoles().size());
}
}
Test with Real Database
When we want to run the tests with the real database, then we need to use the @AutoConfigureTestDatabase annotation with replace attribute set to Replace.NONE. This configuration instructs Spring Boot not to replace the application default DataSource.
@DataJpaTest
@AutoConfigureTestDatabase(replace = Replace.NONE)
class UserRepositoryTest {
Note: In this scenario, we don’t need to include the dependency of embedded database in the
pom.xmlsince the real datasource will not be replaced with test database.
Test with Auto Configured Test Database
In some scenarios, we may want to customize the test data source configuration as we did in our previous tutorial. In such scenarios, we need to perform the following steps. Let’s assume that we are gonna use the h2 in-memory database for our tests.
Step 1: Add the Database Dependency
Add the h2 database dependency into pom.xml
pom.xml
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
Step 2: Define Database Connection Properties
Define h2 database connection properties in src/test/resources/application.properties
src/test/resources/application.properties
#Test Properties
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;MODE=MySQL;NON_KEYWORDS=USER
spring.datasource.username=sa
spring.datasource.password=sa
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true
Note: Here, we have created the
application.propertiesfile in thesrc/test/resourcesdirectory which will be picked up automatically for auto configuring the test database while executing the JUnit tests. Hence, you don’t need to specify any profile specific properties and activate that profile in the JUnit tests.
Step 3: Use @DataJpaTest with @AutoConfigureTestDatabase
Now, we can write the JUnit tests and run them on the AutoConfigured test database.
@DataJpaTest
@AutoConfigureTestDatabase(replace = Replace.NONE)
class UserRepositoryTest {
Note: If you configure the test datasource in a properties file and try to load it with
@TestPropertySource(locations = "classpath:test-database.properties"), then@DataJpaTestwill not load those properties unless untill you specify@AutoConfigureTestDatabase(replace = Replace.NONE)
Test with Embedded DERBY Database
Apache Derby, an Apache DB subproject, is an open source relational database implemented entirely in Java. If you want to use this one for JUnit tests, then add the following dependency
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<scope>runtime</scope>
</dependency>
And use @AutoConfigureTestDatabase annotation with connection attribute set to EmbeddedDatabaseConnection.DERBY
@DataJpaTest
@AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.DERBY)
class UserRepositoryTest {
Note: You don’t have to use
AutoConfigureTestDatabaseto explicitly specify the database connection type if you have only one embedded databse dependency in thepom.xml. i.e., in the classpath.
Test with Embedded H2 Database
H2 is an open source relational database written in Java. If you want to use this one for JUnit tests, then add the following dependency.
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
And use @AutoConfigureTestDatabase annotation with connection attribute set to EmbeddedDatabaseConnection.H2
@DataJpaTest
@AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.H2)
class UserRepositoryTest {
Test with Embedded HSQLDB Database
HSQLDB is an open source relational database written in Java. If you want to use this one for JUnit tests, then add the following dependency.
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</dependency>
And use @AutoConfigureTestDatabase annotation with connection attribute set to EmbeddedDatabaseConnection.HSQLDB
@DataJpaTest
@AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.HSQLDB)
class UserRepositoryTest {
Test with TestEntityManager
Data JPA tests may also inject a TestEntityManager bean, which provides an alternative to the standard JPA EntityManager that is specifically designed for tests.
@DataJpaTest
@AutoConfigureTestDatabase(replace = Replace.NONE)
class UserRepositoryTest {
@Autowired
private TestEntityManager entityManager;
@Test
void testSoftDelete() {
// Add a new user
User user = new User();
user.setDisplayName("Chinna");
user.setEmail("[email protected]");
user = this.entityManager.persistAndFlush(user);
assertEquals("Chinna", user.getDisplayName());
}
}
Conclusion
That’s all folks. In this article, we have explored various scenarios for testing the DAO layer using Spring Boot DataJpaTest annotation.
Thank you for reading.


