Bonjour ! Dans la leçon précédente, nous avons écrit notre première classe de test et utilisé l'assertion assertEquals pour valider un résultat. Vous avez ainsi appris le principe fondamental de la vérification automatisée : comparer un résultat attendu à un résultat réel.
Aujourd'hui, nous allons considérablement enrichir votre boîte à outils de testeur. L'objectif est de maîtriser les assertions les plus courantes de JUnit, telles que assertTrue, assertFalse et assertNotNull. En choisissant l'assertion la plus appropriée pour chaque situation, vous rendrez vos tests non seulement plus puissants, mais aussi beaucoup plus clairs et expressifs.
1. La palette d'assertions de JUnit
assertEquals est parfait pour vérifier une égalité, mais que faire si vous voulez vérifier qu'une valeur est vraie (true), qu'un objet n'est pas nul, ou que deux tableaux contiennent les mêmes éléments ? JUnit fournit une famille complète de méthodes d'assertion pour couvrir tous ces cas de figure.
Toutes ces méthodes sont des méthodes statiques de la classe org.junit.jupiter.api.Assertions. C'est pourquoi nous les importons statiquement pour un code plus concis :import static org.junit.jupiter.api.Assertions.*;
La vidéo suivante présente un excellent panorama des assertions les plus utiles.
Tutoriel Java - tests unitaires
Cette vidéo de la chaîne EvoluNoob, que nous avons déjà vue, détaille plusieurs méthodes d'assertion essentielles.
Regardez attentivement le segment sur les méthodes d'assertion. L'auteur y présente : assertEquals (que vous connaissez déjà) assertTrue et assertFalse pour les conditions booléennes assertSame et assertNotSame pour vérifier l'identité des objets assertNull et assertNotNull pour les vérifications de nullité Notez la structure commune : on teste une condition et on peut fournir un message qui s'affichera en cas d'échec.
Pour résumer et organiser ces informations, voici un tableau des assertions les plus courantes :
| Catégorie | Méthode | Description |
|---|---|---|
| Égalité | assertEquals(expected, actual) |
Vérifie que deux valeurs sont égales (utilise la méthode .equals() pour les objets). |
assertNotEquals(unexpected, actual) |
Vérifie que deux valeurs ne sont pas égales. | |
| Booléen | assertTrue(condition) |
Vérifie que la condition est true. |
assertFalse(condition) |
Vérifie que la condition est false. |
|
| Nullité | assertNull(object) |
Vérifie que l'objet est null. |
assertNotNull(object) |
Vérifie que l'objet n'est pas null. |
|
| Identité | assertSame(expected, actual) |
Vérifie que deux variables référencent exactement le même objet en mémoire (==). |
assertNotSame(unexpected, actual) |
Vérifie que deux variables référencent des objets différents. | |
| Tableaux | assertArrayEquals(expected, actual) |
Vérifie que deux tableaux sont égaux (même longueur et mêmes éléments dans le même ordre). |
2. Focus sur les assertions clés
Approfondissons quelques-unes de ces assertions avec des exemples concrets. Pour cela, imaginons que nous testions un service de gestion d'utilisateurs.
// Classe que nous allons tester
public class User {
private final String username;
private final boolean isAdmin;
public User(String username, boolean isAdmin) {
this.username = username;
this.isAdmin = isAdmin;
}
public String getUsername() { return username; }
public boolean isAdmin() { return isAdmin; }
// NOTE: equals() et hashCode() sont nécessaires pour que assertEquals fonctionne correctement sur les objets.
// Votre IDE peut les générer pour vous.
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return isAdmin == user.isAdmin && java.util.Objects.equals(username, user.username);
}
}
// Service à tester
public class UserService {
public User findByUsername(String username) {
if ("admin".equals(username)) {
return new User("admin", true);
}
return null; // Retourne null si l'utilisateur n'est pas trouvé
}
}
Vérifications de nullité : assertNull et assertNotNull
Ces assertions sont fondamentales pour vérifier le comportement de méthodes qui peuvent retourner null, comme notre findByUsername.
// Dans UserServiceTest.java
@Test
void testFindByUsername() {
UserService userService = new UserService();
// Cas 1: L'utilisateur existe
User admin = userService.findByUsername("admin");
assertNotNull(admin, "L'utilisateur 'admin' ne devrait pas être null.");
// Cas 2: L'utilisateur n'existe pas
User unknown = userService.findByUsername("unknown");
assertNull(unknown, "Un utilisateur inconnu devrait être null.");
}
Vérifications booléennes : assertTrue et assertFalse
Idéal pour tester des méthodes qui retournent un boolean, comme la méthode isAdmin() de notre objet User.
@Test
void testUserPermissions() {
User adminUser = new User("admin", true);
User regularUser = new User("guest", false);
assertTrue(adminUser.isAdmin(), "L'utilisateur admin devrait avoir les droits d'admin.");
assertFalse(regularUser.isAdmin(), "L'utilisateur guest ne devrait pas avoir les droits d'admin.");
}

Égalité de contenu vs. identité d'objet : assertEquals vs. assertSame
C'est une distinction cruciale en Java qui se reflète dans les tests.
assertEquals(obj1, obj2)vérifie siobj1.equals(obj2)est vrai. Les objets peuvent être différents en mémoire mais avoir le même "contenu".assertSame(obj1, obj2)vérifie siobj1 == obj2est vrai. Les deux variables doivent pointer vers la même instance en mémoire.
@Test
void testObjectEqualityAndIdentity() {
User user1 = new User("alex", false);
User user2 = new User("alex", false); // Même contenu, mais nouvelle instance
User user3 = user1; // Même instance
// Vérification d'égalité de contenu
assertEquals(user1, user2, "user1 et user2 devraient être égaux en contenu.");
// Vérification d'identité (référence mémoire)
assertNotSame(user1, user2, "user1 et user2 ne devraient pas être la même instance.");
assertSame(user1, user3, "user1 et user3 devraient être la même instance.");
}
3. Grouper les assertions avec assertAll
Par défaut, dès qu'une assertion échoue dans une méthode de test, l'exécution de cette méthode s'arrête. C'est souvent ce que l'on veut, mais parfois, il est utile de vérifier plusieurs propriétés d'un même objet et de voir tous les échecs en une seule fois. C'est le rôle de assertAll.
La vidéo suivante explique très bien ce concept.
Apprendre le Java #21 Les Tests Unitaire - JUnit5
Cette courte vidéo de Graven - Développement montre de manière très claire l'intérêt et l'utilisation de assertAll.
Regardez le passage sur assertAll. Observez comment il permet d'exécuter plusieurs assertions et de rapporter toutes les erreurs simultanément.
Voici comment nous pourrions l'utiliser pour tester notre objet User :
@Test
void testAdminUserProperties() {
UserService userService = new UserService();
User admin = userService.findByUsername("admin");
assertNotNull(admin); // Vérifions d'abord que l'objet n'est pas null
// Ensuite, vérifions toutes ses propriétés en même temps
assertAll("Propriétés de l'utilisateur admin",
() -> assertEquals("admin", admin.getUsername(), "Le nom d'utilisateur est incorrect."),
() -> assertTrue(admin.isAdmin(), "L'utilisateur devrait être un admin.")
);
}
L'avantage est que si le nom d'utilisateur ET le statut d'admin sont incorrects, JUnit vous signalera les deux erreurs, vous faisant gagner du temps de débogage.

4. Exercice pratique : Test d'un service de produits
Mettez en pratique ce que vous venez d'apprendre. Vous allez tester un service simple qui gère des produits.
Les classes à créer :
-
Dans
src/main/java/com/example/, créez la classeProduct:public class Product { private final long id; private final String name; private double price; private boolean inStock; public Product(long id, String name, double price, boolean inStock) { this.id = id; this.name = name; this.price = price; this.inStock = inStock; } // Générez les getters pour tous les champs. // Générez aussi equals() et hashCode() pour que assertEquals fonctionne. } -
Dans le même package, créez la classe
ProductService:import java.util.HashMap; import java.util.Map; public class ProductService { private final Map<Long, Product> products = new HashMap<>(); public ProductService() { // Ajout de quelques produits pour les tests products.put(1L, new Product(1L, "Laptop Pro", 1200.00, true)); products.put(2L, new Product(2L, "Souris Gamer", 75.50, false)); } public Product findById(long id) { return products.get(id); } }
Votre mission :
Créez une classe de test ProductServiceTest dans src/test/java/com/example/ et écrivez les méthodes de test suivantes :
-
testFindExistingProduct():- Vérifiez qu'un produit existant (ex: ID 1) est bien retourné (
assertNotNull). - Utilisez
assertAllpour vérifier que le nom, le prix et le statutinStockdu produit retourné sont corrects. UtilisezassertEqualsetassertTrue.
- Vérifiez qu'un produit existant (ex: ID 1) est bien retourné (
-
testFindUnavailableProduct():- Vérifiez qu'un produit existant mais hors stock (ex: ID 2) est bien retourné (
assertNotNull). - Vérifiez que son statut
inStockest bienfalseen utilisantassertFalse.
- Vérifiez qu'un produit existant mais hors stock (ex: ID 2) est bien retourné (
-
testFindNonExistingProduct():- Vérifiez que la recherche d'un produit qui n'existe pas (ex: ID 99) retourne
nullen utilisantassertNull.
- Vérifiez que la recherche d'un produit qui n'existe pas (ex: ID 99) retourne
Prenez le temps de réaliser cet exercice. C'est en pratiquant que ces concepts s'ancrent durablement.
Conclusion
Vous disposez maintenant d'un solide arsenal d'assertions pour valider avec précision le comportement de votre code. Savoir choisir la bonne assertion (assertTrue pour un booléen, assertNull pour une absence d'objet, assertEquals pour une valeur) est une compétence clé qui rend vos tests plus robustes et plus faciles à comprendre pour vous et vos futurs collaborateurs.
Les points clés à retenir :
- Utilisez
assertNotNulletassertNullpour les cas où une méthode peut retourner (ou non) un objet. - Utilisez
assertTrueetassertFalsepour valider des conditions ou des méthodes retournant un booléen. - Faites la distinction entre
assertEquals(égalité de valeur) etassertSame(identité de référence). - Utilisez
assertAllpour regrouper des vérifications sur un même objet et obtenir un rapport complet de toutes les erreurs.
Dans la prochaine leçon, nous aborderons le cycle de vie des tests. Vous apprendrez à utiliser les annotations @BeforeEach et @AfterEach pour initialiser et nettoyer l'état de vos tests, une technique essentielle pour écrire des tests propres et indépendants.