How to Mock React Refs
Mocking React refs is a common necessity when writing unit tests for
components that interact directly with the DOM or external libraries.
This article provides a direct, step-by-step guide on how to mock React
refs using Jest and React Testing Library, covering scenarios like
mocking useRef hooks, stubbing DOM methods, and testing
forwarded refs.
Mocking DOM Methods on Refs
The most common reason to mock a ref is to test component behavior
that triggers a DOM method, such as .focus(),
.scrollIntoView(), or .play() on a video
element. Instead of mocking the React hook itself, you can mock the DOM
prototype method before rendering the component.
import { render, screen } from '@testing-library/react';
import MyComponent from './MyComponent';
describe('MyComponent', () => {
it('should focus the input on mount', () => {
// Mock the focus method on the HTMLInputElement prototype
const focusMock = jest.fn();
HTMLInputElement.prototype.focus = focusMock;
render(<MyComponent />);
expect(focusMock).toHaveBeenCalledTimes(1);
});
});Mocking the useRef Hook
If you need to control the exact value of ref.current
during a test, you can mock the useRef hook directly using
jest.spyOn. This is useful when your component logic
depends on specific properties of a ref that are difficult to simulate
in a test environment.
import React from 'react';
import { render } from '@testing-library/react';
import MyComponent from './MyComponent';
describe('MyComponent with useRef mock', () => {
it('should use the mocked ref value', () => {
const mockRef = {
current: {
getBoundingClientRect: () => ({ width: 100, height: 50 }),
},
};
// Spy on React.useRef and return the mock object
jest.spyOn(React, 'useRef').mockReturnValue(mockRef);
render(<MyComponent />);
// Assertions based on the mocked bounding rect values
});
});Mocking Forwarded Refs
When testing components wrapped in React.forwardRef, you
can pass a mocked ref object directly as a prop from your test suite.
This allows you to verify that the child component correctly assigns the
ref to its underlying DOM element.
import React from 'react';
import { render } from '@testing-library/react';
import ForwardedInput from './ForwardedInput';
describe('ForwardedInput', () => {
it('assigns the ref to the input element', () => {
const ref = React.createRef();
render(<ForwardedInput ref={ref} />);
expect(ref.current).toBeInstanceOf(HTMLInputElement);
});
});