React Testing Library helps you check if your React components work correctly by simulating how users interact with them.
React Testing Library integration in NextJS
import { render, screen, fireEvent } from '@testing-library/react'; import Component from './Component'; test('description', () => { render(<Component />); const element = screen.getByText('some text'); fireEvent.click(element); expect(something).toBe(someValue); });
render shows your component in a test environment.
screen helps find elements like buttons or text.
import { render, screen } from '@testing-library/react'; import Hello from './Hello'; test('shows hello message', () => { render(<Hello />); expect(screen.getByText('Hello World')).toBeInTheDocument(); });
import { render, screen, fireEvent } from '@testing-library/react'; import Counter from './Counter'; test('increments counter on button click', () => { render(<Counter />); const button = screen.getByRole('button', { name: 'Increment' }); fireEvent.click(button); expect(screen.getByText('Count: 1')).toBeInTheDocument(); });
This example shows a simple toggle button component and a test that clicks the button to check if the text and aria-pressed attribute update correctly.
import React, { useState } from 'react'; export default function Toggle() { const [on, setOn] = useState(false); return ( <> <button aria-pressed={on} onClick={() => setOn(!on)}> {on ? 'Turn Off' : 'Turn On'} </button> <p>{on ? 'The switch is ON' : 'The switch is OFF'}</p> </> ); } // Test file: Toggle.test.js import { render, screen, fireEvent } from '@testing-library/react'; import Toggle from './Toggle'; test('toggles text when button is clicked', () => { render(<Toggle />); const button = screen.getByRole('button'); expect(screen.getByText('The switch is OFF')).toBeInTheDocument(); fireEvent.click(button); expect(screen.getByText('The switch is ON')).toBeInTheDocument(); expect(button).toHaveAttribute('aria-pressed', 'true'); });
Use aria- attributes to improve accessibility and make elements easier to find in tests.
Prefer screen.getByRole or screen.getByText to find elements like a user would.
Run tests often to catch problems early and keep your app working well.
React Testing Library helps test React components by simulating user actions.
Use render, screen, and fireEvent to write simple, clear tests.
Focus tests on what users see and do, not on internal details.
Practice
Solution
Step 1: Understand React Testing Library's role
It focuses on testing components by simulating how users interact with them and what they see.Step 2: Compare options with this role
Only To test React components by simulating user interactions and checking visible output describes testing user interactions and visible output, which matches React Testing Library's purpose.Final Answer:
To test React components by simulating user interactions and checking visible output -> Option CQuick Check:
Testing user behavior = D [OK]
- Confusing testing library with styling or state management tools
- Thinking it optimizes rendering performance
- Assuming it manages app state
render function from React Testing Library?Solution
Step 1: Identify the official package for React Testing Library
The correct package is '@testing-library/react' for React Testing Library functions.Step 2: Check import syntax
React Testing Library exports render as a named export, so use curly braces around render.Final Answer:
import { render } from '@testing-library/react'; -> Option AQuick Check:
Named import from '@testing-library/react' = B [OK]
- Using default import instead of named import
- Importing from wrong package like 'react-dom' or 'next/testing'
- Missing curly braces around render
screen.getByText('Hello World') return?import { render, screen } from '@testing-library/react';
function Greeting() {
return <h1>Hello World</h1>;
}
test('renders greeting text', () => {
render(<Greeting />);
const element = screen.getByText('Hello World');
return element;
});Solution
Step 1: Understand what render and screen.getByText do
render displays the component in a virtual DOM; screen.getByText finds the first element with matching text.Step 2: Check the component output
Greeting returns <h1>Hello World</h1>, so screen.getByText('Hello World') finds this <h1> element.Final Answer:
The <h1> element containing 'Hello World' -> Option BQuick Check:
getByText finds matching element = C [OK]
- Thinking getByText returns null if found
- Confusing screen with undefined variable
- Assuming getByText returns multiple elements
import { render, screen, fireEvent } from '@testing-library/react';
function Button() {
const [count, setCount] = React.useState(0);
return <button onClick={() => setCount(count + 1)}>Clicked {count} times</button>;
}
test('increments count on click', () => {
render(<Button />);
const button = screen.getByRole('button');
fireEvent.click(button);
expect(button.textContent).toBe('Clicked 1 times');
});Solution
Step 1: Check imports for React usage
The component uses React.useState but React is not imported, causing a runtime error.Step 2: Verify other parts
fireEvent.click and getByRole('button') are correct usage; expect checks textContent correctly.Final Answer:
Missing import of React from 'react' -> Option DQuick Check:
React must be imported to use React.useState = A [OK]
- Assuming fireEvent is wrong instead of userEvent
- Thinking getByRole('button') is incorrect
- Checking innerHTML instead of textContent
import { render, screen, waitFor } from '@testing-library/react';
import React from 'react';
function DataDisplay() {
const [data, setData] = React.useState(null);
React.useEffect(() => {
fetch('/api/data').then(res => res.json()).then(setData);
}, []);
if (!data) return <div>Loading...</div>;
return <div>Data: {data.value}</div>;
}
test('shows fetched data', async () => {
global.fetch = jest.fn(() => Promise.resolve({
json: () => Promise.resolve({ value: 'Hello' })
}));
render(<DataDisplay />);
await waitFor(() => screen.getByText('Data: Hello'));
expect(screen.getByText('Data: Hello')).toBeInTheDocument();
});Solution
Step 1: Check mocking of fetch
The test mocks global.fetch to return a resolved promise with expected data, which is correct for simulating API calls.Step 2: Verify waiting for async UI update
Using waitFor to wait until the text 'Data: Hello' appears is the right way to handle async rendering in tests.Final Answer:
Correctly mocks fetch and waits for async update with waitFor -> Option AQuick Check:
Mock fetch + waitFor async UI = A [OK]
- Trying to trigger fetch with fireEvent instead of mocking
- Not waiting for async content before assertions
- Forgetting to cleanup mocks (not critical here)
Ready to prove it?
Pass the test and this pattern moves unknown
