API
React Testing Library
re-exports everything from DOM Testing Library
as well
as these methods:
render
render
Optionsrender
Resultcleanup
act
renderHook
renderHook
OptionsrenderHook
Resultconfigure
configure
Options
render
function render(
ui: React.ReactElement<any>,
options?: {
/* You won't often use this, expand below for docs on options */
},
): RenderResult
Render into a container which is appended to document.body
.
import {render} from '@testing-library/react'
render(<div />)
import {render} from '@testing-library/react'
import '@testing-library/jest-dom'
test('renders a message', () => {
const {asFragment, getByText} = render(<Greeting />)
expect(getByText('Hello, world!')).toBeInTheDocument()
expect(asFragment()).toMatchInlineSnapshot(`
<h1>Hello, World!</h1>
`)
})
render
Options
You won't often need to specify options, but if you ever do, here are the
available options which you could provide as a second argument to render
.
container
By default, React Testing Library
will create a div
and append that div
to
the document.body
and this is where your React component will be rendered. If
you provide your own HTMLElement container
via this option, it will not be
appended to the document.body
automatically.
For example: If you are unit testing a tablebody
element, it cannot be a child
of a div
. In this case, you can specify a table
as the render container
.
const table = document.createElement('table')
const {container} = render(<TableBody {...props} />, {
container: document.body.appendChild(table),
})
baseElement
If the container
is specified, then this defaults to that, otherwise this
defaults to document.body
. This is used as the base element for the queries as
well as what is printed when you use debug()
.
hydrate
If hydrate is set to true, then it will render with ReactDOM.hydrate. This may be useful if you are using server-side rendering and use ReactDOM.hydrate to mount your components.
legacyRoot
This option is only available when tests run with React 18 and earlier.
By default we'll render with support for concurrent features (i.e.
ReactDOMClient.createRoot
).
However, if you're dealing with a legacy app that requires rendering like in
React 17 (i.e.
ReactDOM.render
) then you
should enable this option by setting legacyRoot: true
.
wrapper
Pass a React Component as the wrapper
option to have it rendered around the
inner element. This is most useful for creating reusable custom render functions
for common data providers. See setup for examples.
queries
Queries to bind. Overrides the default set from DOM Testing Library
unless
merged.
// Example, a function to traverse table contents
import * as tableQueries from 'my-table-query-library'
import {queries} from '@testing-library/react'
const {getByRowColumn, getByText} = render(<MyTable />, {
queries: {...queries, ...tableQueries},
})
See helpers for guidance on using utility functions to create custom queries.
Custom queries can also be added globally by following the custom render guide.
render
Result
The render
method returns an object that has a few properties:
...queries
The most important feature of render
is that the queries from
DOM Testing Library are automatically returned with their
first argument bound to the baseElement, which defaults to
document.body
.
See Queries for a complete list.
Example
const {getByLabelText, queryAllByTestId} = render(<Component />)
container
The containing DOM node of your rendered React Element (rendered using
ReactDOM.render
). It's a div
. This is a regular DOM node, so you can call
container.querySelector
etc. to inspect the children.
Tip: To get the root element of your rendered element, use
container.firstChild
.NOTE: When that root element is a React Fragment,
container.firstChild
will only get the first child of that Fragment, not the Fragment itself.
🚨 If you find yourself using
container
to query for rendered elements then you should reconsider! The other queries are designed to be more resilient to changes that will be made to the component you're testing. Avoid usingcontainer
to query for elements!
baseElement
The containing DOM node where your React Element is rendered in the container.
If you don't specify the baseElement
in the options of render
, it will
default to document.body
.
This is useful when the component you want to test renders something outside the container div, e.g. when you want to snapshot test your portal component which renders its HTML directly in the body.
Note: the queries returned by the
render
looks into baseElement, so you can use queries to test your portal component without the baseElement.
debug
NOTE: It's recommended to use
screen.debug
instead.
This method is a shortcut for console.log(prettyDOM(baseElement))
.
import React from 'react'
import {render} from '@testing-library/react'
const HelloWorld = () => <h1>Hello World</h1>
const {debug} = render(<HelloWorld />)
debug()
// <div>
// <h1>Hello World</h1>
// </div>
// you can also pass an element: debug(getByTestId('messages'))
// and you can pass all the same arguments to debug as you can
// to prettyDOM:
// const maxLengthToPrint = 10000
// debug(getByTestId('messages'), maxLengthToPrint, {highlight: false})
This is a simple wrapper around prettyDOM
which is also exposed and comes from
DOM Testing Library
.
rerender
It'd probably be better if you test the component that's doing the prop updating to ensure that the props are being updated correctly (see the Guiding Principles section). That said, if you'd prefer to update the props of a rendered component in your test, this function can be used to update props of the rendered component.
import {render} from '@testing-library/react'
const {rerender} = render(<NumberDisplay number={1} />)
// re-render the same component with different props
rerender(<NumberDisplay number={2} />)
unmount
This will cause the rendered component to be unmounted. This is useful for testing what happens when your component is removed from the page (like testing that you don't leave event handlers hanging around causing memory leaks).
This method is a pretty small abstraction over
ReactDOM.unmountComponentAtNode
import {render} from '@testing-library/react'
const {container, unmount} = render(<Login />)
unmount()
// your component has been unmounted and now: container.innerHTML === ''
asFragment
Returns a DocumentFragment
of your rendered component. This can be useful if
you need to avoid live bindings and see how your component reacts to events.
import React, {useState} from 'react'
import {render, fireEvent} from '@testing-library/react'
const TestComponent = () => {
const [count, setCounter] = useState(0)
return (
<button onClick={() => setCounter(count => count + 1)}>
Click to increase: {count}
</button>
)
}
const {getByText, asFragment} = render(<TestComponent />)
const firstRender = asFragment()
fireEvent.click(getByText(/Click to increase/))
// This will snapshot only the difference between the first render, and the
// state of the DOM after the click event.
// See https://github.com/jest-community/snapshot-diff
expect(firstRender).toMatchDiffSnapshot(asFragment())
cleanup
Unmounts React trees that were mounted with render.
This is called automatically if your testing framework (such as mocha, Jest or Jasmine) injects a global
afterEach()
function into the testing environment. If not, you will need to callcleanup()
after each test.
For example, if you're using the ava testing
framework, then you would need to use the test.afterEach
hook like so:
import {cleanup, render} from '@testing-library/react'
import test from 'ava'
test.afterEach(cleanup)
test('renders into document', () => {
render(<div />)
// ...
})
// ... more tests ...
Failing to call cleanup
when you've called render
could result in a memory
leak and tests which are not "idempotent" (which can lead to difficult to debug
errors in your tests).
act
This is a light wrapper around the
react
act
function. All it does is
forward all arguments to the act function if your version of react supports
act
. It is recommended to use the import from @testing-library/react
over
react
for consistency reasons.
renderHook
This is a convenience wrapper around render
with a custom test component. The
API emerged from a popular testing pattern and is mostly interesting for
libraries publishing hooks. You should prefer render
since a custom test
component results in more readable and robust tests since the thing you want to
test is not hidden behind an abstraction.
function renderHook<
Result,
Props,
Q extends Queries = typeof queries,
Container extends Element | DocumentFragment = HTMLElement,
BaseElement extends Element | DocumentFragment = Container
>(
render: (initialProps: Props) => Result,
options?: RenderHookOptions<Props, Q, Container, BaseElement>,
): RenderHookResult<Result, Props>
Example:
import {renderHook} from '@testing-library/react'
test('returns logged in user', () => {
const {result} = renderHook(() => useLoggedInUser())
expect(result.current).toEqual({name: 'Alice'})
})
renderHook
Options
renderHook
Options initialProps
Declares the props that are passed to the render-callback when first invoked.
These will not be passed if you call rerender
without props.
import {renderHook} from '@testing-library/react'
test('returns logged in user', () => {
const {result, rerender} = renderHook((props = {}) => props, {
initialProps: {name: 'Alice'},
})
expect(result.current).toEqual({name: 'Alice'})
rerender()
expect(result.current).toEqual({name: undefined})
})
NOTE: When using
renderHook
in conjunction with thewrapper
andinitialProps
options, theinitialProps
are not passed to thewrapper
component. To provide props to thewrapper
component, consider a solution like this:const createWrapper = (Wrapper, props) => {
return function CreatedWrapper({ children }) {
return <Wrapper {...props}>{children}</Wrapper>;
};
};
...
{
wrapper: createWrapper(Wrapper, { value: 'foo' }),
}
renderHook
Options wrapper
renderHook
Result
The renderHook
method returns an object that has a few properties:
result
Holds the value of the most recently committed return value of the render-callback:
import {renderHook} from '@testing-library/react'
const {result} = renderHook(() => {
const [name, setName] = useState('')
React.useEffect(() => {
setName('Alice')
}, [])
return name
})
expect(result.current).toBe('Alice')
Note that the value is held in result.current
. Think of result
as a
ref for the most
recently committed value.
rerender
Renders the previously rendered render-callback with the new props:
import {renderHook} from '@testing-library/react'
const {rerender} = renderHook(({name = 'Alice'} = {}) => name)
// re-render the same hook with different props
rerender({name: 'Bob'})
unmount
Unmounts the test hook.
import {renderHook} from '@testing-library/react'
const {unmount} = renderHook(({name = 'Alice'} = {}) => name)
unmount()
configure
Changes global options. Basic usage can be seen at Configuration Options.
React Testing Library also has dedicated options.
import {configure} from '@testing-library/react'
configure({reactStrictMode: true})
configure
Options
reactStrictMode
When enabled, <StrictMode>
is
rendered around the inner element. Defaults to false
.