Kurs vibe coding z AI · Moduł 11: Spotify Clone
Testing - Jest & React Testing Library
W tej lekcji2
Pisanie testów dla komponentów React.
Setup
npm install --save-dev @testing-library/react @testing-library/jest-dom jestComponent Tests
// Button.tsx
export function Button({ onClick, children }: {
onClick: () => void;
children: React.ReactNode
}) {
return (
<button onClick={onClick} className="btn">
{children}
</button>
);
}
// Button.test.tsx
import { render, screen, fireEvent } from '@testing-library/react';
import { Button } from './Button';
describe('Button', () => {
it('renders children', () => {
render(<Button onClick={() => {}}>Click me</Button>);
expect(screen.getByText('Click me')).toBeInTheDocument();
});
it('calls onClick when clicked', () => {
const handleClick = jest.fn();
render(<Button onClick={handleClick}>Click</Button>);
fireEvent.click(screen.getByText('Click'));
expect(handleClick).toHaveBeenCalledTimes(1);
});
});Do zobaczenia!
Kod do tej lekcji: App.tsx
'use client';
import { useState } from 'react';
export default function CreatePlaylistModal() {
const [isOpen, setIsOpen] = useState(true);
const [name, setName] = useState('');
const [description, setDescription] = useState('');
const [isPublic, setIsPublic] = useState(true);
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (name.trim()) {
alert(`Utworzono playlistę: ${name}`);
setIsOpen(false);
}
};
if (!isOpen) {
return (
<div className="min-h-screen bg-black text-white flex items-center justify-center">
<button
onClick={() => setIsOpen(true)}
className="px-6 py-3 bg-green-500 text-black font-semibold rounded-full hover:bg-green-400"
>
Utwórz playlistę
</button>
</div>
);
}
return (
<div className="min-h-screen bg-black/75 flex items-center justify-center p-4">
<div className="bg-gray-900 rounded-lg max-w-md w-full p-6 text-white">
<h2 className="text-2xl font-bold mb-6">Utwórz playlistę</h2>
<form onSubmit={handleSubmit}>
<div className="mb-4">
<label className="block text-sm font-semibold mb-2">
Nazwa
</label>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Moja playlista"
className="w-full bg-gray-800 text-white px-4 py-3 rounded outline-none focus:ring-2 focus:ring-green-500"
autoFocus
/>
</div>
<div className="mb-4">
<label className="block text-sm font-semibold mb-2">
Opis (opcjonalnie)
</label>
<textarea
value={description}
onChange={(e) => setDescription(e.target.value)}
placeholder="Dodaj opis..."
className="w-full bg-gray-800 text-white px-4 py-3 rounded outline-none resize-none focus:ring-2 focus:ring-green-500"
rows={3}
/>
</div>
<div className="mb-6">
<label className="flex items-center gap-3 cursor-pointer">
<input
type="checkbox"
checked={isPublic}
onChange={(e) => setIsPublic(e.target.checked)}
className="w-5 h-5"
/>
<span>Ustaw playlistę jako publiczną</span>
</label>
</div>
<div className="flex gap-3">
<button
type="button"
onClick={() => setIsOpen(false)}
className="flex-1 py-3 border border-gray-700 rounded-full font-semibold hover:border-white"
>
Anuluj
</button>
<button
type="submit"
disabled={!name.trim()}
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"
>
Utwórz
</button>
</div>
</form>
</div>
</div>
);
}Widzisz błąd w tej lekcji?
Sprawdź się
Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.
1. Jakie biblioteki instalujemy do testowania komponentów React?
2. Do czego służy fireEvent.click() w teście?
Zadania praktyczne w grze
- Klikanie w kolejności
Kliknij elementy, aby zbudować import narzędzi testowych:
- Układanie w pionie
Uporządkuj kroki testu sprawdzającego kliknięcie przycisku: