Interview questions with answers
React Testing Library interview questions and answers
Queries by role, user-event, async utilities and testing behaviour. Open any question to read its model answer; the multiple-choice set marks the right option and explains it.
- Subjective
- 30
- Objective
- 30
Subjective questions 30
1What is the guiding principle of React Testing Library?Asked almost every time
"The more your tests resemble the way your software is used, the more confidence they can give you." Test behaviour through what users see and do (roles, labels, text, clicks, typing), not implementation details such as state, props or component internals. Tests then survive refactors and catch real bugs.
2Explain getBy, queryBy and findBy queries.Asked almost every time
getBy* returns the element or throws if there is none (or several): use it when the element must be there. queryBy* returns null when missing: use it to assert absence. findBy* returns a promise that retries until the element appears or a timeout: use it for async UI. Each has *AllBy* variants for many elements.
3Which queries should you prefer?Asked almost every time
In priority order: getByRole (with name), getByLabelText, getByPlaceholderText, getByText, getByDisplayValue, then getByAltText and getByTitle, and getByTestId only as a last resort. Role queries also check that your markup is accessible.
4user-event vs. fireEvent: what is the difference?Asked almost every time
fireEvent dispatches a single DOM event. @testing-library/user-event simulates full interactions as a browser would: typing fires keydown, keypress, input and keyup per character, clicking includes pointer and focus events, and it respects disabled elements. Prefer userEvent.setup() and await its methods.
5How do you test a component that fetches data on mount?Asked almost every time
Mock the API with MSW (or mock the fetch function), render the component, assert the loading state, then await screen.findByText(...) for the loaded data. Also test the error state by making the handler return an error.
6How do you test accessibility with React Testing Library?Asked almost every time
Prefer role and label queries, which fail if elements are not accessible; add jest-axe for automated checks (expect(await axe(container)).toHaveNoViolations()); and test keyboard interaction with user-event tab and keyboard.
7What is the difference between getByText and getByRole with a name?Asked almost every time
getByText finds any element containing the text. getByRole('button', { name: 'Save' }) finds a button whose accessible name is Save, which is stricter and more meaningful: it ensures the element is actually a button users and assistive technology can find.
8How do you test asynchronous UI updates?Very often asked
Use await screen.findByText(...) for elements that appear later, or await waitFor(() => expect(...)) for other conditions. Use waitForElementToBeRemoved for loaders. Avoid wrapping everything in act manually; RTL's utilities already do it.
9How do you mock API calls in component tests?Very often asked
Mock at the network level with Mock Service Worker (MSW): define handlers that return fixture responses, so components and data libraries run unchanged. Override handlers per test for errors or empty states. Mocking fetch directly also works but couples tests to the client.
10How do you test components that need providers (router, store, query client)?Very often asked
Write a custom render that wraps the UI in the needed providers, with a fresh store or QueryClient per test, and pass it options such as the initial route. Re-export everything from RTL with this render so tests stay short.
11What does the 'not wrapped in act(...)' warning mean?Very often asked
A state update happened after the test stopped waiting, often from an unawaited promise or timer. The fix is usually to await the resulting UI change with findBy or waitFor, or to await user-event calls, rather than adding act everywhere.
12How do you test keyboard navigation?Very often asked
Use await user.tab() to move focus and expect(element).toHaveFocus(), await user.keyboard('{Enter}') or {ArrowDown} to trigger interactions, and check that focus moves and content updates as expected.
13How do you test a modal dialog?Very often asked
Open it through the UI, find it with getByRole('dialog', { name: ... }), assert focus moves inside, test closing with the close button and Escape, and assert it disappears with queryByRole returning null (or waitForElementToBeRemoved).
14What is waitForElementToBeRemoved?Very often asked
An async helper that waits until an element (such as a spinner) leaves the DOM. It fails immediately if the element is not present at the start, which catches tests that assume a loading state that never appeared.
15How do you set up user-event correctly in v14?Very often asked
Call const user = userEvent.setup() before rendering (or at the start of the test) and await every interaction such as await user.click(button). With fake timers, pass advanceTimers: jest.advanceTimersByTime.
16How do you write a custom render function?Very often asked
Create a helper that wraps render with your providers (theme, router, store, query client), re-export everything from RTL with your render overriding the default, and import it in tests instead of the library.
17How do you test components that use timers?Very often asked
Use fake timers, set up user-event with advanceTimers, then advance time inside act or use async timer helpers, and assert the result. Restore real timers after each test.
18How do you test a form?Often asked
Find inputs by their labels, type with user-event, submit by clicking the button found by role, then assert on the visible result or on the mocked submit handler's arguments. Also test validation messages and disabled states.
19How do you test custom hooks?Often asked
Use renderHook from RTL, which renders the hook in a test component and gives result.current; wrap updates with act. Prefer testing hooks through components that use them when practical.
20What is screen and why use it?Often asked
screen is bound to document.body, so you can query without destructuring from render. It keeps tests consistent and easier to read; within(element) scopes queries to part of the page.
21Why avoid testing implementation details?Often asked
Tests that check internal state, private methods or component structure break on harmless refactors and can pass while the UI is broken. Testing outputs users see gives fewer false failures and more real protection.
22What is within?Often asked
It scopes queries to a container element, for example within(screen.getByRole('row', { name: /Asha/ })).getByRole('button', { name: 'Edit' }), so you target the right element when the page repeats similar ones.
23How do you test a select or combobox?Often asked
Use await user.selectOptions(screen.getByRole('combobox', { name: 'Country' }), 'India') for native selects. For custom comboboxes, type into the input, find the option with findByRole('option', { name }) and click it.
24How do you test that a callback prop was called?Often asked
Pass a mock such as const onSave = jest.fn(), interact with the UI, then assert expect(onSave).toHaveBeenCalledWith(expectedData). This tests the component's contract without inspecting its internals.
25Why avoid container.querySelector in tests?Often asked
It ties tests to markup and class names that users cannot see, so refactors break tests without changing behaviour. Role, label and text queries reflect how people use the UI.
26How do you test error boundaries?Often asked
Render a child that throws inside the boundary, suppress the expected console error with a spy, and assert that the fallback UI appears, and that a reset button recovers if the boundary supports it.
27How do you test file uploads?Often asked
Find the file input by its label and call await user.upload(input, new File(['hello'], 'hello.txt', { type: 'text/plain' })), then assert input.files[0] and the resulting UI.
28What does jest-dom add?Sometimes asked
Custom matchers such as toBeInTheDocument, toBeVisible, toHaveTextContent, toBeDisabled, toHaveAttribute and toHaveAccessibleName, which make DOM assertions readable and give clearer failure messages.
29How do you debug what RTL sees?Sometimes asked
screen.debug() prints the DOM, screen.logTestingPlaygroundURL() gives a link that suggests queries, and failing queries print the DOM and available roles.
30What does logRoles do?Sometimes asked
It prints every element's implicit ARIA role in a container, helping you find the right getByRole query when you are unsure what role an element has.
Objective questions 30
1Which query is recommended first?Asked almost every time
Why: Role queries mirror how users and assistive technologies find elements.
2Which query should assert that an element is absent?Asked almost every time
Why: queryBy returns null instead of throwing.
3Which query waits for an element to appear?Asked almost every time
Why: findBy returns a promise that retries.
4Which query waits for data loaded after mount?Asked almost every time
Why: find queries return a promise.
5Which is the most user-focused way to find a Save button?Asked almost every time
Why: Role plus accessible name.
6How must user-event v14 interactions be called?Asked almost every time
Why: They are async.
7Which library simulates realistic typing and clicking?Very often asked
Why: user-event fires the full event sequence.
8Which utility retries an assertion until it passes?Very often asked
Why: waitFor polls the callback until it stops throwing.
9Which tool mocks APIs at the network level?Very often asked
Why: Mock Service Worker intercepts requests.
10Which matcher comes from jest-dom?Very often asked
Why: jest-dom adds DOM-specific matchers.
11Which matcher checks the focused element?Very often asked
Why: From jest-dom.
12Which helper waits for a spinner to disappear?Very often asked
Why: Fails if missing at start.
13How do you test an Escape key closing a dialog?Very often asked
Why: Simulates the key.
14Which library adds automated a11y checks to tests?Very often asked
Why: toHaveNoViolations.
15Why write a custom render?Very often asked
Why: Theme, router, store.
16How do you scope queries to one part of the page?Often asked
Why: within binds queries to an element.
17Which renders a custom hook?Often asked
Why: renderHook returns result.current.
18What does getByRole('button', { name: 'Save' }) match?Often asked
Why: The name option uses the accessible name.
19What should a test assert on?Often asked
Why: Behaviour over implementation.
20Which selects an option in a native select?Often asked
Why: Pass the option value or label.
21Which uploads a file through an input?Often asked
Why: Pass a File object.
22Which prints elements' ARIA roles?Often asked
Why: Helps choose queries.
23What should a test assert about a callback prop?Often asked
Why: Test the contract.
24Why avoid querySelector by class names?Often asked
Why: Ties tests to implementation.
25Which role does a modal dialog have?Often asked
Why: Query with getByRole('dialog').
26Which prints the current DOM?Sometimes asked
Why: It logs a formatted DOM tree.
27user-event methods in v14 should be…Sometimes asked
Why: They return promises.
28Which is the last-resort query?Sometimes asked
Why: Test IDs are invisible to users.
29user-event with fake timers needs…Sometimes asked
Why: Otherwise interactions hang.
30What does within(row) do?Sometimes asked
Why: Targets repeated elements.
Track what you have practised and search every bank in your dashboard.
Start learning