Dans ce chapitre nous allons faire une petite aparté sur les tests unitaires dans le cadre de React. Comment tester les hooks et nos composants ?
Configuration de l'environnement
Dans le cadre de react-dom
, nos tests auront besoin d'interagir avec le DOM, on pourra utiliser jsdom
pour que notre code fonctionne sur NodeJS. Dans le cadre de vitest, on l'ajoutera à notre configuration :
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
test: {
environment: 'jsdom',
setupFiles: './test/setup.js'
}
})
Dans le fichier setup.js
on s'assurera que notre environnement est bien nettoyé après chaque test.
import {afterEach} from "vitest";
import {cleanup} from "@testing-library/react";
afterEach(() => {
cleanup()
})
Tester un hook
Une hook est une fonction qui ne peut être exécuté que dans le contexte d'un composant. On pourra utiliser la librairie @testing-library/react
qui nous offrira 2 méthodes utiles en lien avec les tests de hooks
renderHook()
, qui permet d'exécuter le code d'un hook en renvoyant le résultat dans un objet.act()
, qui permet de faire un changement d'état (appeler un setter par exemple).
Voici un petit exemple d'utilisation :
import {describe, it, expect} from "vitest";
import {useIncrement} from "../src/hooks/useIncrement.js";
import {act, renderHook} from "@testing-library/react";
describe('useIncrement', () => {
it('should use the default value', () => {
const {result} = renderHook(() => useIncrement({base: 5}))
expect(result.current.count).toBe(5)
})
it('should increment value', () => {
const {result} = renderHook(() => useIncrement({base: 5}))
act(() => result.current.increment())
expect(result.current.count).toBe(6)
})
it('should not bypass max', () => {
const {result} = renderHook(() => useIncrement({base: 5, max: 7}))
act(() => result.current.increment())
act(() => result.current.increment())
act(() => result.current.increment())
act(() => result.current.increment())
expect(result.current.count).toBe(7)
})
})
Tester un composant
Pour tester un composant le plus simple est de vérifier que la structure HTML corresponde à ce que l'on attend. On pourra aussi utiliser la librairie @testing-library/user-event
pour simuler les évènements navigateur.
import {describe, it, expect} from "vitest";
import {render, screen} from "@testing-library/react";
import {Alert} from "../src/components/Alert.jsx";
import {userEvent} from "@testing-library/user-event";
describe('<Alert>', () => {
it('should render correctly', () => {
const {container} = render(<Alert type="danger">Erreur</Alert>)
expect(container.firstChild).toMatchInlineSnapshot()
})
it('should close the alert on click', async () => {
const {container} = render(<Alert type="danger">Erreur</Alert>)
await userEvent.click(screen.getByText('Fermer'))
expect(container.firstChild).toMatchInlineSnapshot('null')
})
})