Testing
Unit testing, integration testing, E2E testing, and mock strategies.
Overview
Testing ensures reliability and prevents regressions in Next.js apps.
Key Concepts
- Jest — Unit and integration testing
- React Testing Library — Component testing
- Cypress/Playwright — E2E testing
- Mocking — Mock API routes and external services
- Server Component Testing — Test async server components
Code Examples
// components/__tests__/Button.test.jsx
import { render, screen, fireEvent } from '@testing-library/react';
import Button from '../Button';
describe('Button', () => {
it('renders correctly', () => {
render(<Button>Click me</Button>);
expect(screen.getByRole('button')).toHaveTextContent('Click me');
});
it('calls onClick when clicked', () => {
const handleClick = jest.fn();
render(<Button onClick={handleClick}>Click</Button>);
fireEvent.click(screen.getByRole('button'));
expect(handleClick).toHaveBeenCalledTimes(1);
});
});
// E2E test with Cypress
describe('Login flow', () => {
it('logs in successfully', () => {
cy.visit('/login');
cy.get('input[name="email"]').type('user@example.com');
cy.get('input[name="password"]').type('password');
cy.get('button[type="submit"]').click();
cy.url().should('include', '/dashboard');
});
});
// Mock API routes
jest.mock('next/navigation', () => ({
useRouter: () => ({ push: jest.fn() })
}));
// Server component test
async function testServerComponent() {
const ProductPage = (await import('../app/product/page')).default;
render(<ProductPage params={{ id: '1' }} />);
expect(await screen.findByText('Product Name')).toBeInTheDocument();
}
Practice
Write comprehensive tests for a Next.js page with form submission.