React Component Tests with Vitest
React Component Tests with Vitest
~15 Min. Lesezeit Zuletzt aktualisiert am August 8, 2026
EXACTLY as block 11 of the Symfony course explained WHY tests build confidence, the SAME principle applies to React – Vitest (the test framework MATCHING Vite) AND React Testing Library are TODAY's standard.
Installing the tools
npm install --save-dev vitest @testing-library/react @testing-library/jest-dom jsdomConfiguring Vite for tests
export default defineConfig({
plugins: [react()],
test: {
environment: 'jsdom',
setupFiles: './src/test-setup.ts',
},
});import '@testing-library/jest-dom';environment: 'jsdom' simulates a browser DOM in Node.js, WITHOUT starting a REAL browser – FAST enough to run HUNDREDS of tests in seconds.
The first component test
import { describe, it, expect } from 'vitest';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import CreateProjectForm from './CreateProjectForm';
function renderWithQueryClient(ui: React.ReactElement) {
const queryClient = new QueryClient();
return render(
<QueryClientProvider client={queryClient}>{ui}</QueryClientProvider>,
);
}
describe('CreateProjectForm', () => {
it('shows an input field and a button', () => {
renderWithQueryClient(<CreateProjectForm />);
expect(screen.getByPlaceholderText('Project name')).toBeInTheDocument();
expect(screen.getByRole('button', { name: /create project/i })).toBeInTheDocument();
});
});renderWithQueryClient WRAPS the component WITH the SAME QueryClientProvider from chapter 73 – CreateProjectForm uses useCreateProject (chapter 78) INTERNALLY, which would ABORT with a runtime error WITHOUT a provider.
Simulating user interaction
it('updates the input field while typing', async () => {
const user = userEvent.setup();
renderWithQueryClient(<CreateProjectForm />);
const input = screen.getByPlaceholderText('Project name');
await user.type(input, 'New Project');
expect(input).toHaveValue('New Project');
});@testing-library/user-event simulates REAL keyboard/mouse events (keystroke BY keystroke) instead of fireEvent's SYNTHETIC events – CLOSER to actual user behavior, EXACTLY THE philosophy behind Testing Library: "test HOW a user uses the application".
Running the tests
npm run testTipp: getByRole instead of getByTestId is DELIBERATELY Testing Library's RECOMMENDED choice – IT SIMULTANEOUSLY checks THAT the component is ACCESSIBLE (screen readers use the SAME ARIA roles), A USEFUL side effect of good tests.