What You’ll Learn in This Tutorial
✓ Vitest setup
✓ Writing basic tests
✓ Mocking
✓ Coverage
✓ UI mode
Step 1: Setup
npm install -D vitest @testing-library/react @testing-library/jest-dom jsdom
// vitest.config.ts
import { defineConfig } from 'vitest/config';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
test: {
environment: 'jsdom',
globals: true,
setupFiles: './src/test/setup.ts',
},
});
// src/test/setup.ts
import '@testing-library/jest-dom';
Step 2: Basic Tests
// src/utils/math.ts
export function add(a: number, b: number) {
return a + b;
}
// src/utils/math.test.ts
import { describe, it, expect } from 'vitest';
import { add } from './math';
describe('add', () => {
it('should add two numbers', () => {
expect(add(1, 2)).toBe(3);
});
it('should handle negative numbers', () => {
expect(add(-1, 1)).toBe(0);
});
});
Step 3: Component Tests
// src/components/Button.tsx
interface Props {
onClick: () => void;
children: React.ReactNode;
}
export function Button({ onClick, children }: Props) {
return <button onClick={onClick}>{children}</button>;
}
// src/components/Button.test.tsx
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { describe, it, expect, vi } from 'vitest';
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', async () => {
const handleClick = vi.fn();
render(<Button onClick={handleClick}>Click me</Button>);
await userEvent.click(screen.getByRole('button'));
expect(handleClick).toHaveBeenCalledTimes(1);
});
});
Step 4: Mocking
// Module mock
vi.mock('./api', () => ({
fetchUser: vi.fn().mockResolvedValue({ id: 1, name: 'Test' }),
}));
// Function mock
const mockFn = vi.fn();
mockFn.mockReturnValue(42);
mockFn.mockResolvedValue({ data: 'test' });
// Spy
const spy = vi.spyOn(console, 'log');
console.log('test');
expect(spy).toHaveBeenCalledWith('test');
Step 5: Async Tests
import { describe, it, expect, vi } from 'vitest';
describe('async tests', () => {
it('handles async operations', async () => {
const result = await fetchData();
expect(result).toBeDefined();
});
it('handles promises', () => {
return expect(asyncFn()).resolves.toBe('value');
});
it('handles rejections', () => {
return expect(failingFn()).rejects.toThrow('error');
});
});
Step 6: Running Tests
# Run tests
npm run test
# Watch mode
npm run test -- --watch
# UI mode
npm run test -- --ui
# Coverage
npm run test -- --coverage
Step 7: package.json Scripts
{
"scripts": {
"test": "vitest",
"test:ui": "vitest --ui",
"test:coverage": "vitest --coverage"
}
}
Summary
Vitest is a fast testing framework integrated with Vite. With Jest-compatible APIs for smooth migration and UI mode for efficient debugging.
← Back to list