0 Tage Serie
javascript / intermediate
Snippet

Testen asynchroner React-Zustands-Fallbacks mit Testing Library

Das Testen asynchroner Zustandsänderungen in React-Komponenten erfordert das Mocken von Netzwerkschnittstellen sowie die Überprüfung von Ladezuständen und Fehleranzeigen. Durch die Kombination von `waitFor` und asynchronem `userEvent` werden Microtasks und Zustandsaktualisierungen ohne Race Conditions abgearbeitet.

snippet.js
javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { describe, it, expect, vi } from 'vitest';
import { UserProfile } from './UserProfile';
describe('UserProfile async error boundaries', () => {
it('renders an error message when the API rejects', async () => {
const user = userEvent.setup();
const mockFetch = vi.spyOn(global, 'fetch').mockRejectedValueOnce(
new Error('Service Unavailable')
);
render(<UserProfile userId="user_123" />);
const refreshButton = screen.getByRole('button', { name: /refresh/i });
await user.click(refreshButton);
expect(screen.getByText(/loading/i)).toBeInTheDocument();
await waitFor(() => {
expect(screen.getByRole('alert')).toHaveTextContent('Service Unavailable');
});
mockFetch.mockRestore();
});
});
react
Erklärung
1
vi.spyOn(global, 'fetch').mockRejectedValueOnce(new Error('Service Unavailable'));
Mockt die globale fetch-Funktion und simuliert einen einmaligen asynchronen Netzwerkfehler.
2
await user.click(refreshButton);
Löst Benutzerinteraktionen asynchron aus und simuliert das echte Event-Bubbling im Browser.
3
await waitFor(() => { expect(screen.getByRole('alert')).toHaveTextContent(...); });
Wiederholt die DOM-Überprüfung zyklisch, bis die asynchrone Fehlerbehandlung das Re-Rendering auslöst.