Tests d'intégration JPA - Les fondamentaux
1. Introduction et concepts
Test d'intégration JPA : Teste les entités, repositories et requêtes avec une vraie base de données (ou H2 en mémoire).
Différence avec test unitaire :
- ✅ Teste les mappings JPA réels
- ✅ Valide les contraintes DB
- ✅ Vérifie les requêtes SQL générées
- ✅ Détecte les problèmes N+1
- ❌ Plus lent qu'un test unitaire
2. Configuration de base
2.1 Dépendances Maven
<dependencies>
<!-- Spring Boot Test (inclut JUnit 5, Mockito, AssertJ) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- H2 pour tests en mémoire -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
<!-- Testcontainers (optionnel, pour base réelle) -->
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
<version>1.19.3</version>
<scope>test</scope>
</dependency>
</dependencies>
2.2 Configuration de test (application-test.properties)
# src/test/resources/application-test.properties # H2 Database en mémoire spring.datasource.url=jdbc:h2:mem:testdb spring.datasource.driver-class-name=org.h2.Driver spring.datasource.username=sa spring.datasource.password= # JPA/Hibernate spring.jpa.hibernate.ddl-auto=create-drop spring.jpa.show-sql=true spring.jpa.properties.hibernate.format_sql=true spring.jpa.properties.hibernate.use_sql_comments=true # Désactiver cache pour tests prédictibles spring.jpa.properties.hibernate.cache.use_second_level_cache=false # Logging SQL détaillé logging.level.org.hibernate.SQL=DEBUG logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE logging.level.org.hibernate.orm.jdbc.bind=TRACE
3. Anatomie d'un test JPA
3.1 Test Repository basique
@DataJpaTest // ← Annotation clé
@ActiveProfiles("test")
class ProductRepositoryTest {
@Autowired
private ProductRepository productRepository;
@Autowired
private TestEntityManager entityManager; // ← Utilitaire de test JPA
@Test
void shouldSaveAndFindProduct() {
// Given
Product product = new Product();
product.setName("Test Product");
product.setPrice(new BigDecimal("99.99"));
// When
Product saved = productRepository.save(product);
entityManager.flush(); // Force SQL immédiat
entityManager.clear(); // Vide le cache (simule nouvelle session)
// Then
Product found = productRepository.findById(saved.getId()).orElseThrow();
assertThat(found.getName()).isEqualTo("Test Product");
assertThat(found.getPrice()).isEqualByComparingTo("99.99");
}
}
Annotations essentielles :
@DataJpaTest: Configure uniquement la couche JPA (pas de serveur web)@AutoConfigureTestDatabase(replace = NONE): Utilise la DB configurée (pas H2 auto)@Sql: Exécute un script SQL avant le test
3.2 TestEntityManager - Les commandes clés
@Test
void demonstrateTestEntityManager() {
Product product = new Product("Laptop", new BigDecimal("1200"));
// persist() : INSERT sans flush immédiat
entityManager.persist(product);
// flush() : Force l'exécution des SQL en attente
entityManager.flush();
// clear() : Vide le contexte de persistance (cache 1er niveau)
entityManager.clear();
// find() : SELECT en DB (car cache vidé)
Product fromDb = entityManager.find(Product.class, product.getId());
// detach() : Détache une entité du contexte
entityManager.detach(fromDb);
}
4. Tests des associations
4.1 OneToMany bidirectionnel
@Test
void shouldCascadeOrderToOrderItems() {
// Given
User user = new User("john@test.com");
entityManager.persist(user);
Order order = new Order(user);
OrderItem item1 = new OrderItem(order, "Product A", 2);
OrderItem item2 = new OrderItem(order, "Product B", 1);
order.addItem(item1); // Méthode helper bidirectionnelle
order.addItem(item2);
// When
entityManager.persist(order); // CASCADE.PERSIST sur items
entityManager.flush();
entityManager.clear();
// Then
Order found = entityManager.find(Order.class, order.getId());
assertThat(found.getItems()).hasSize(2);
assertThat(found.getItems())
.extracting(OrderItem::getProductName)
.containsExactlyInAnyOrder(
- eadl/bloc3/dev_av/td2-b.txt
- Dernière modification : il y a 10 mois
- de
jcheron