I just started trying out react testing library with jest, going through a tutorial and have the following question:
const App = () => {
return (
<form onSubmit={handleSubmit}>
<div>
<label>Name</label>
<input value={name} onChange={(e) => setName(e.target.value)} />
</div>
<div>
<label>Email</label>
<input value={email} onChange={(e) => setEmail(e.target.value)} />
</div>
<button>Add User</button>
</form>
);
}
the test should locate the button but shows an error:
test('shows 2 inputs and a button', async () => {
render(<App />);
const btn = await screen.findByRole('button');
expect(btn).toHaveLength(1)
})
this however works:
test('shows 2 inputs and a button', async () => {
render(<App />);
const btn = await screen.findByRole('button');
expect(btn).toBeInTheDocument()
})
Why is the first test failing locating the button with toHaveLength?
It fails because screen.findByRole('button')
returns a single element, not an array of elements. The toHaveLength
method is used to check the length of an array, so it doesn't work with a single element.
To check the number of buttons in the document, you should use screen.findAllByRole('button')
, which returns an array of elements, and then you can use toHaveLength
.
test('shows 2 inputs and a button', async () => {
render(<App />);
const btns = await screen.findAllByRole('button');
expect(btns).toHaveLength(1);
});