How to Test Component Functions In React Testing Library
How should I test a function inside a component in React Testing Library? The short answer is: you shouldn't.Β You might be thinking we need to mock the function and expect it to be called. However, this is not the correct approach. Instead, you should be testing behavior, and what a real user would see inside their browser.
For demonstration purposes, take the following component as an example which renders a dialog that can be toggled on and off using a useState
hook.
import { useState } from 'react'
export default function App() {
const [toggled, setToggled] = useState(false)
const toggle = () => {
setToggled(!toggled)
}
return (
<div>
<dialog open={toggled} data-testid="dialog">Dialog</dialog>
<button onClick={toggle}>Toggle</button>
</div>
)
}
Imagine we want to test the toggle
function inside it to verify it toggles the correct state. However, you should avoid testing implementation details as they will make your test suite fragile. If your implementation changes, so do your tests, otherwise, they will break.

Testing Component Methods the Right Way
Instead of directly testing functions, we should be testing behaviorΒ β that is, whether the button toggles the correct attribute. This can be done in the following way in React Testing Library:
import React from 'react'
import { fireEvent, render, screen } from '@testing-library/react'
import { Dialog } from '@components'
describe('Dialog', () => {
it('should toggle the dialog on and off', () => {
render(<Dialog />)
const dialog = screen.getByTestId('dialog')
const button = screen.getByRole('button')
expect(dialog).not.toHaveAttribute('open')
fireEvent.click(button)
expect(dialog).toHaveAttribute('open')
})
})
First, we grab the elements from the component using getByTestId
and getByRole
, then use the fireEvent
API to trigger a click on the button. This will call the function, which means we can verify its effect on the open
attribute on our dialog
. Make sure you also verify the absence of the attribute prior to clicking the button.
Now we avoided directly testing implementation details of our functions defined inside our components, and instead tested how the component should behave. If you are interested in more unit test best practices, make sure you have a look at the article below.

Unlimited access to hundred of tutorials
Access to exclusive interactive lessons
Remove ads to learn without distractions