
Assertions avec Jest (`expect`)
Apprenez à utiliser la fonction `expect` de Jest et ses puissants matchers, y compris ceux de @testing-library/jest-dom, pour vérifier efficacement les résultats de vos tests React.
Vérifier les résultats : Le rôle des assertions
Ecrire un test ne consiste pas seulement à effectuer des actions (rendre un composant, simuler un clic). La partie la plus cruciale est de vérifier que le résultat de ces actions est bien celui attendu. C'est le rôle des assertions. Dans l'écosystème Jest, l'outil principal pour écrire des assertions est la fonction globale `expect()`.
La fonction `expect()` prend en argument la valeur que vous souhaitez tester (le "sujet" de votre assertion). Elle retourne ensuite un objet "expectative" sur lequel vous enchaînez une fonction appelée "matcher". Le matcher est ce qui effectue la comparaison ou la vérification réelle. Par exemple, dans `expect(resultat).toBe(5)`, `expect(resultat)` est l'expectative et `.toBe(5)` est le matcher qui vérifie si `resultat` est strictement égal à `5`.
Si l'assertion (la condition vérifiée par le matcher) est vraie, le test continue. Si elle est fausse, Jest lève une erreur immédiatement, faisant échouer le test et affichant généralement un message descriptif indiquant la différence entre la valeur attendue et la valeur reçue.
Les Matchers de base de Jest
Jest fournit une riche bibliothèque de matchers intégrés pour couvrir de nombreux cas de figure courants :
- Egalité :
.toBe(valeur): Vérifie l'égalité stricte (===). Utile pour les types primitifs (nombres, chaînes, booléens)..toEqual(valeur): Vérifie l'égalité "en profondeur" (récursive). Indispensable pour comparer des objets ou des tableaux, car il compare leurs contenus plutôt que leurs références en mémoire.
- Vérité / Fausseté :
.toBeTruthy(): Vérifie si la valeur est "vraie" dans un contexte booléen (différent de `false`, `0`, `''`, `null`, `undefined`, `NaN`)..toBeFalsy(): Vérifie si la valeur est "fausse" dans un contexte booléen..toBeNull(): Vérifie si la valeur est exactement `null`..toBeDefined(): Vérifie si la valeur n'est pas `undefined`..toBeUndefined(): Vérifie si la valeur est `undefined`.
- Nombres :
.toBeGreaterThan(nombre).toBeGreaterThanOrEqual(nombre).toBeLessThan(nombre).toBeLessThanOrEqual(nombre).toBeCloseTo(nombre, nbDecimales): Utile pour les nombres à virgule flottante, pour éviter les erreurs d'arrondi.
- Chaînes de caractères :
.toMatch(regexp | string): Vérifie si une chaîne correspond à une expression régulière ou contient une sous-chaîne.
- Tableaux et Itérables :
.toContain(item): Vérifie si un tableau ou un itérable contient un élément spécifique..toHaveLength(nombre): Vérifie la longueur d'un tableau ou d'une chaîne.
- Exceptions :
.toThrow(erreur?): Vérifie si une fonction lève une exception lorsqu'elle est appelée.
Matchers pour les Mocks (Fonctions espionnes)
Lorsque vous utilisez des fonctions mockées avec `jest.fn()` (pour simuler des callbacks, des appels API, etc.), Jest fournit des matchers spécifiques pour vérifier comment ces mocks ont été utilisés :
.toHaveBeenCalled(): Vérifie si la fonction mockée a été appelée au moins une fois..toHaveBeenCalledTimes(nombre): Vérifie combien de fois la fonction mockée a été appelée..toHaveBeenCalledWith(arg1, arg2, ...): Vérifie si la fonction mockée a été appelée avec des arguments spécifiques..toHaveBeenLastCalledWith(arg1, arg2, ...): Vérifie les arguments du dernier appel à la fonction mockée..toHaveReturned()/.toHaveReturnedTimes(nombre)/.toHaveReturnedWith(valeur): Vérifie ce que la fonction mockée a retourné.
test('callback is called with correct data on submit', () => {
const handleSubmit = jest.fn(); // Créer un mock
render( );
// Simuler la saisie et la soumission...
await userEvent.type(screen.getByLabelText(/name/i), 'Test User');
await userEvent.click(screen.getByRole('button', { name: /submit/i }));
expect(handleSubmit).toHaveBeenCalledTimes(1); // A-t-elle été appelée une fois ?
expect(handleSubmit).toHaveBeenCalledWith({ name: 'Test User' }); // Avec les bonnes données ?
});Extension sémantique avec `@testing-library/jest-dom`
Si les matchers de base de Jest sont puissants, ils ne sont pas toujours très expressifs lorsqu'il s'agit de vérifier l'état du DOM. Par exemple, pour vérifier si un élément est dans le document, vous pourriez faire `expect(screen.getByText('Bonjour')).not.toBeNull()`, mais ce n'est pas très lisible.
C'est là qu'intervient la bibliothèque `@testing-library/jest-dom`. Elle étend l'objet `expect` de Jest en lui ajoutant une série de matchers personnalisés spécifiquement conçus pour travailler avec le DOM. Ces matchers rendent vos assertions beaucoup plus claires, sémantiques et directement liées à ce que l'utilisateur pourrait percevoir.
Comme vu dans la configuration, il suffit généralement d'importer cette bibliothèque une fois dans votre fichier de setup (`setupTests.js` ou équivalent) pour que ses matchers soient disponibles globalement :
// Dans src/setupTests.js
import '@testing-library/jest-dom';Matchers courants de `jest-dom`
Voici quelques-uns des matchers les plus utiles fournis par `jest-dom` :
.toBeInTheDocument(): Vérifie si l'élément est présent dans le `document` (ou le fragment) actuel. Le plus fondamental après une requête `getBy*` ou `findBy*`.expect(screen.getByRole('heading')).toBeInTheDocument();.toBeVisible(): Vérifie si l'élément est visible pour l'utilisateur (non caché par CSS `display: none`, `visibility: hidden`, `opacity: 0`, taille nulle, ou `hidden` attribute)..toBeDisabled()/.toBeEnabled(): Vérifie si un élément de formulaire est désactivé ou activé..toHaveValue(valeur | tableauDeValeurs | nombre): Vérifie la valeur actuelle d'un élément de formulaire (`input`, `select`, `textarea`)..toHaveTextContent(texte | regexp): Vérifie le contenu textuel d'un noeud, y compris ses descendants. Plus flexible que `.toBe()` pour le texte..toHaveAttribute(nomAttr, valeurAttendue?): Vérifie si un élément possède un attribut donné, et éventuellement sa valeur..toHaveClass(classe1, classe2, ..., options?): Vérifie si un élément possède une ou plusieurs classes CSS..toHaveFocus(): Vérifie si l'élément a actuellement le focus..toBeRequired(): Vérifie si un élément de formulaire est marqué comme obligatoire (`required`)..toBeChecked(): Pour les checkboxes ou radio buttons.
test('form interaction and state', async () => {
render( );
const input = screen.getByLabelText(/email/i);
const checkbox = screen.getByLabelText(/terms/i);
const submitButton = screen.getByRole('button', { name: /submit/i });
expect(input).toBeInTheDocument();
expect(input).toBeEnabled();
expect(input).toHaveValue('');
expect(checkbox).not.toBeChecked();
expect(submitButton).toBeDisabled(); // Bouton désactivé initialement
await userEvent.type(input, 'test@example.com');
await userEvent.click(checkbox);
expect(input).toHaveValue('test@example.com');
expect(checkbox).toBeChecked();
expect(submitButton).toBeEnabled(); // Devient activé
});Négation avec `.not`
Tous les matchers de Jest (y compris ceux ajoutés par `jest-dom`) peuvent être précédés de `.not` pour affirmer la condition inverse.
expect(screen.queryByText(/error/i)).not.toBeInTheDocument();
expect(button).not.toBeDisabled();
expect(value).not.toBeNull();C'est particulièrement utile avec les requêtes `queryBy*` pour vérifier l'absence d'un élément : `expect(screen.queryByRole('alert')).toBeNull();` est équivalent et souvent préféré à `expect(screen.queryByRole('alert')).not.toBeInTheDocument();` pour la clarté, mais les deux fonctionnent.
En combinant la puissance de `expect` de Jest avec les matchers sémantiques de `@testing-library/jest-dom`, vous pouvez écrire des assertions claires, précises et robustes qui valident efficacement le comportement de vos composants React du point de vue de l'utilisateur.