I'm trying to test my UsersTable page in React, but the testing library gets the elements before they have time to render. Please check my code below:
UsersTable.js
import React, { useState, useEffect } from 'react';
import { Link } from 'react-router-dom';
import Table from 'react-bootstrap/Table';
import { fetchUsers } from 'api';
function UsersTable() {
const [users, setUsers] = useState([]);
useEffect(() => {
const getUsers = async () => {
const data = await fetchUsers();
setUsers(data);
};
getUsers();
}, []);
const renderUsers = () => users.map((user) => {
const { id, fullName, email } = user;
return (
<tr key={ id } >
<td>
<Link to={ `user/${id}` }>{ fullName }</Link>
</td>
<td>
<Link to={ `user/${id}/mail` }>{ email }</Link>
</td>
</tr>
);
});
return (
<div data-testid='userTest' className="users-table">
<h1>Users</h1>
<Table striped borderless>
<thead>
<tr style={{
borderBottom: "1px solid #cccccc"
}}>
<th>User</th>
<th>Email</th>
</tr>
</thead>
<tbody>
{ renderUsers() }
</tbody>
</Table>
</div>
);
}
export default UsersTable;
userTable.test.js
import { render } from '@testing-library/react'
import React from 'react';
import { BrowserRouter as Router } from 'react-router-dom';
import '@testing-library/jest-dom/extend-expect';
import UserTable from '../components/users/UserTable';
test("Test #1: Count Users", async () => {
const component = render(
<Router>
<UserTable />
</Router>
);
const users = component.getByTestId('userTest')
expect(users.querySelectorAll('tr').length).toBe(193)
})
Note: <Router> prevents the error Error: Uncaught [Error: Invariant failed: You should not use <Link> outside a <Router>
Expect: Expecting to have 192 users + 1 row containing thead, but instead I get 1 row containing only the thead.