@DataJpaTest for repository testing in JUnit - Build an Automation Script
package com.example.demo; import static org.assertj.core.api.Assertions.assertThat; 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; @DataJpaTest class UserRepositoryTest { @Autowired private UserRepository userRepository; @Test void testSaveAndFindUser() { // Create a new User User user = new User(); user.setName("Alice"); // Save the User User savedUser = userRepository.save(user); // Retrieve the User by id Optional<User> retrievedUserOpt = userRepository.findById(savedUser.getId()); // Verify the User is present assertThat(retrievedUserOpt).isPresent(); User retrievedUser = retrievedUserOpt.get(); // Verify the name is 'Alice' assertThat(retrievedUser.getName()).isEqualTo("Alice"); } } // Entity class package com.example.demo; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; 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; } } // Repository interface package com.example.demo; import org.springframework.data.jpa.repository.JpaRepository; public interface UserRepository extends JpaRepository<User, Long> { }
This test class uses @DataJpaTest to load only the JPA components and an in-memory database for fast testing.
The UserRepository is injected with @Autowired. The test method testSaveAndFindUser creates a new User entity, saves it, and then retrieves it by its generated ID.
Assertions check that the retrieved user exists and that its name matches the expected value 'Alice'.
The entity class User uses JPA annotations for ID generation and mapping.
This setup ensures the repository works correctly with the database layer without loading the full application context.
Now add data-driven testing with 3 different User names to verify saving and retrieving works for each.
Practice
@DataJpaTest in Spring Boot testing?Solution
Step 1: Understand the role of @DataJpaTest
@DataJpaTest is designed to test JPA repositories specifically, setting up only database-related components.Step 2: Recognize the default database setup
It uses an in-memory database by default to keep tests fast and isolated.Final Answer:
To test only the JPA repositories with an in-memory database setup -> Option DQuick Check:
@DataJpaTest = repository testing with in-memory DB [OK]
- Thinking it tests the whole application
- Confusing it with @SpringBootTest
- Assuming it tests service or controller layers
@DataJpaTest for repository testing?Solution
Step 1: Identify annotations used with @DataJpaTest
@DataJpaTest automatically includes @Transactional and often uses @AutoConfigureTestDatabase to control DB setup.Step 2: Understand @SpringBootTest role
@SpringBootTest loads the full application context, which is not typical with @DataJpaTest that loads a slice for repositories.Final Answer:
@SpringBootTest -> Option BQuick Check:
@DataJpaTest excludes full context, so no @SpringBootTest [OK]
- Using @SpringBootTest with @DataJpaTest unnecessarily
- Confusing @MockBean usage in repository tests
- Ignoring transactional rollback behavior
@DataJpaTest:
@DataJpaTest
public class UserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
void testSaveAndFind() {
User user = new User(null, "Alice");
userRepository.save(user);
Optional<User> found = userRepository.findByName("Alice");
assertTrue(found.isPresent());
}
}
What will be the test result when executed?Solution
Step 1: Analyze @DataJpaTest behavior
@DataJpaTest sets up an in-memory database and configures repositories automatically with transactional rollback.Step 2: Check test logic
The test saves a user and then finds it by name. Since the repository is autowired and database is in-memory, the user will be found.Final Answer:
Test passes because the user is saved and found correctly -> Option CQuick Check:
Save + find with @DataJpaTest = pass [OK]
- Assuming database is empty or uninitialized
- Forgetting @DataJpaTest provides @Transactional by default
- Thinking repository needs manual initialization
@DataJpaTest:
@DataJpaTest
public class ProductRepositoryTest {
@Autowired
private ProductRepository productRepository;
@Test
void testFindById() {
Product product = new Product(1L, "Book");
productRepository.save(product);
Product found = productRepository.findById(1L).orElse(null);
assertNotNull(found);
}
}
The test fails with an AssertionError on assertNotNull(found). What is the most likely cause?Solution
Step 1: Check entity configuration
If the Product class lacks @Entity, JPA won't map it, so save won't persist anything.Step 2: Understand repository autowiring and transactions
@DataJpaTest autowires repositories and runs tests in transactions by default, so these are unlikely causes.Final Answer:
The Product entity is missing an @Entity annotation -> Option AQuick Check:
Missing @Entity means no persistence [OK]
- Assuming @Transactional is missing in @DataJpaTest
- Thinking save() doesn't work in tests
- Ignoring entity annotations
@DataJpaTest. The method returns a list of users with age greater than a given value. Which of the following is the best practice to ensure your test is reliable and isolated?Solution
Step 1: Understand test isolation with @DataJpaTest
@DataJpaTest uses an in-memory database that starts empty for each test, so you must insert test data.Step 2: Avoid external dependencies and mocks for repository tests
Using production DB or mocks defeats the purpose of repository testing with real JPA behavior.Final Answer:
Use @DataJpaTest with an in-memory database and insert test users before querying -> Option AQuick Check:
Insert test data in @DataJpaTest for reliable queries [OK]
- Connecting to production DB in tests
- Relying on existing data without setup
- Mocking repository methods instead of real queries
Ready to prove it?
Pass the test and this pattern moves unknown
