Cours Vibe coding avec l'IA · Module 11: Clone de Spotify

Tests - Jest & React Testing Library

1 min de lecture
Dans cette leçon2

Écrire des tests pour des composants React.

Mise en place

1npm install --save-dev @testing-library/react @testing-library/jest-dom jest

Tests de composants

1// Button.tsx
2export function Button({ onClick, children }: {
3  onClick: () => void;
4  children: React.ReactNode
5}) {
6  return (
7    <button onClick={onClick} className="btn">
8      {children}
9    </button>
10  );
11}
12
13// Button.test.tsx
14import { render, screen, fireEvent } from '@testing-library/react';
15import { Button } from './Button';
16
17describe('Button', () => {
18  it('renders children', () => {
19    render(<Button onClick={() => {}}>Click me</Button>);
20    expect(screen.getByText('Click me')).toBeInTheDocument();
21  });
22
23  it('calls onClick when clicked', () => {
24    const handleClick = jest.fn();
25    render(<Button onClick={handleClick}>Click</Button>);
26
27    fireEvent.click(screen.getByText('Click'));
28    expect(handleClick).toHaveBeenCalledTimes(1);
29  });
30});

À très bientôt !

Code de cette leçon : App.tsx
1'use client';
2
3import { useState } from 'react';
4
5export default function CreatePlaylistModal() {
6  const [isOpen, setIsOpen] = useState(true);
7  const [name, setName] = useState('');
8  const [description, setDescription] = useState('');
9  const [isPublic, setIsPublic] = useState(true);
10
11  const handleSubmit = (e: React.FormEvent) => {
12    e.preventDefault();
13    if (name.trim()) {
14      alert(`Playlist créée : ${name}`);
15      setIsOpen(false);
16    }
17  };
18
19  if (!isOpen) {
20    return (
21      <div className="min-h-screen bg-black text-white flex items-center justify-center">
22        <button
23          onClick={() => setIsOpen(true)}
24          className="px-6 py-3 bg-green-500 text-black font-semibold rounded-full hover:bg-green-400"
25        >
26          Créer une playlist
27        </button>
28      </div>
29    );
30  }
31
32  return (
33    <div className="min-h-screen bg-black/75 flex items-center justify-center p-4">
34      <div className="bg-gray-900 rounded-lg max-w-md w-full p-6 text-white">
35        <h2 className="text-2xl font-bold mb-6">Créer une playlist</h2>
36
37        <form onSubmit={handleSubmit}>
38          <div className="mb-4">
39            <label className="block text-sm font-semibold mb-2">
40              Nom
41            </label>
42            <input
43              type="text"
44              value={name}
45              onChange={(e) => setName(e.target.value)}
46              placeholder="Ma playlist"
47              className="w-full bg-gray-800 text-white px-4 py-3 rounded outline-none focus:ring-2 focus:ring-green-500"
48              autoFocus
49            />
50          </div>
51
52          <div className="mb-4">
53            <label className="block text-sm font-semibold mb-2">
54              Description (facultatif)
55            </label>
56            <textarea
57              value={description}
58              onChange={(e) => setDescription(e.target.value)}
59              placeholder="Ajoute une description..."
60              className="w-full bg-gray-800 text-white px-4 py-3 rounded outline-none resize-none focus:ring-2 focus:ring-green-500"
61              rows={3}
62            />
63          </div>
64
65          <div className="mb-6">
66            <label className="flex items-center gap-3 cursor-pointer">
67              <input
68                type="checkbox"
69                checked={isPublic}
70                onChange={(e) => setIsPublic(e.target.checked)}
71                className="w-5 h-5"
72              />
73              <span>Rendre la playlist publique</span>
74            </label>
75          </div>
76
77          <div className="flex gap-3">
78            <button
79              type="button"
80              onClick={() => setIsOpen(false)}
81              className="flex-1 py-3 border border-gray-700 rounded-full font-semibold hover:border-white"
82            >
83              Annuler
84            </button>
85            <button
86              type="submit"
87              disabled={!name.trim()}
88              className="flex-1 py-3 bg-green-500 rounded-full text-black font-semibold hover:bg-green-400 disabled:bg-gray-700 disabled:text-gray-500"
89            >
90              Créer
91            </button>
92          </div>
93        </form>
94      </div>
95    </div>
96  );
97}

Tu as repéré une erreur dans cette leçon ?

Teste tes connaissances

Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.

  1. 1. Quelles bibliothèques installe-t-on pour tester des composants React ?

  2. 2. À quoi sert fireEvent.click() dans un test ?

Tâches pratiques dans le jeu

  • Clique dans l'ordre

    Clique pour construire l'import des utilitaires de test :

  • Tri vertical

    Ordonne les étapes d'un test qui vérifie le clic sur un bouton :

Articles utiles