Testing is a key aspect of building reliable and maintainable applications. In Spring Boot, @DataJpaTest
is a specialized test slice that focuses on JPA components such as repositories and entity mappings. It’s incredibly fast and isolated from other parts of your application, making it ideal for testing data access layers.
This post will guide you through using Spring Boot @DataJpaTest Testing for repositories and service layers, including how to mock dependencies and validate behavior.

๐ฆ Project Setup
Make sure your pom.xml
contains:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<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-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>test</scope> </dependency> </dependencies> |
We use H2 in-memory database for testing purposes to keep tests isolated and fast.
๐ Package Structure
1 2 3 4 5 6 7 8 9 10 11 12 13 |
com.kscodes.springboot โโโ model โ โโโ User.java โโโ repository โ โโโ UserRepository.java โโโ service โ โโโ UserService.java โโโ test โโโ repository โโโ UserRepositoryTest.java |
๐งฑ Entity Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
package com.kscodes.springboot.model; import jakarta.persistence.*; @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String email; // Getters and Setters } |
๐ฆ Repository Interface
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package com.kscodes.springboot.repository; import com.kscodes.springboot.model.User; import org.springframework.data.jpa.repository.JpaRepository; import java.util.Optional; public interface UserRepository extends JpaRepository<User, Long> { Optional<User> findByEmail(String email); } |
โ Testing Repository with @DataJpaTest
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
package com.kscodes.springboot.repository; import com.kscodes.springboot.model.User; 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.Optional; import static org.assertj.core.api.Assertions.assertThat; @DataJpaTest public class UserRepositoryTest { @Autowired private UserRepository userRepository; @Test public void testFindByEmail() { User user = new User(); user.setName("John"); user.setEmail("john@example.com"); userRepository.save(user); Optional<User> result = userRepository.findByEmail("john@example.com"); assertThat(result).isPresent(); assertThat(result.get().getName()).isEqualTo("John"); } } |
This is the core of Spring Boot @DataJpaTest Testing: isolated repository logic tested with an in-memory database.
๐งช Service Layer Example (Optional)
Suppose we want to test UserService
that depends on UserRepository
. While @DataJpaTest
is primarily for repositories, we can use it in combination with @Import
.
๐ก UserService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
package com.kscodes.springboot.service; import com.kscodes.springboot.model.User; import com.kscodes.springboot.repository.UserRepository; import org.springframework.stereotype.Service; import java.util.Optional; @Service public class UserService { private final UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository = userRepository; } public Optional<User> findUserByEmail(String email) { return userRepository.findByEmail(email); } } |
๐งช Testing Service with @DataJpaTest + @Import
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
package com.kscodes.springboot.service; import com.kscodes.springboot.model.User; import com.kscodes.springboot.repository.UserRepository; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.Import; import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; @DataJpaTest @Import(UserService.class) public class UserServiceTest { @Autowired private UserService userService; @Autowired private UserRepository userRepository; @Test public void testFindUserByEmail() { User user = new User(); user.setName("Alice"); user.setEmail("alice@example.com"); userRepository.save(user); Optional<User> result = userService.findUserByEmail("alice@example.com"); assertThat(result).isPresent(); assertThat(result.get().getName()).isEqualTo("Alice"); } } |
โ๏ธ Configuration Tips
@DataJpaTest
automatically rolls back transactions after each test.- It excludes other Spring beans (like controllers or services) unless explicitly imported via
@Import
. - Use
@AutoConfigureTestDatabase(replace = NONE)
if you want to test with a real DB.
๐ Summary
In this guide, you learned how to use Spring Boot @DataJpaTest Testing for:
- Writing isolated tests for repositories
- Leveraging H2 in-memory database for fast test execution
- Using
@Import
to include services in@DataJpaTest