admin管理员组文章数量:1415116
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 '../ponents/users/UserTable';
test("Test #1: Count Users", async () => {
const ponent = render(
<Router>
<UserTable />
</Router>
);
const users = ponent.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
.
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 '../ponents/users/UserTable';
test("Test #1: Count Users", async () => {
const ponent = render(
<Router>
<UserTable />
</Router>
);
const users = ponent.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
.
- 1 See testing-library./docs/dom-testing-library/api-async – jonrsharpe Commented Jun 8, 2022 at 22:23
-
Are you mocking your
fetchusers
? What you need to garantee its that the ponent is rendered the table with rows and cells, not the number of td chids... Take a look in what you should avoid with testing library here. – Luis Paulo Pinto Commented Jun 8, 2022 at 23:15 -
1
But if you want to test the number of
tr
, you should avoid useselectors
like you did. The proper way in this case would beconst trElements = screen.getAllByRole('row')
andexpect(trElements).toHaveLength(193)
– Luis Paulo Pinto Commented Jun 8, 2022 at 23:17 - Thank you for your advice, Luis. I ended up testing that the ponents are rendered and tested some user inputs. Thanks a lot! – Gerald Hoxha Commented Jun 11, 2022 at 8:42
2 Answers
Reset to default 0expect(getByTestId('userTest').children.length).toBe(193);
The issue Is that your test is trying to access the DOM elements before the useEffect
hook in UsersTable
has pleted fetching and rendering the data.
You can use reacts @testing-library
's findBy
or waitFor
methods to wait for the ponents to render your ponent data asynchronously.
import { render, screen, waitFor } from '@testing-library/react';
import React from 'react';
import { BrowserRouter as Router } from 'react-router-dom';
import '@testing-library/jest-dom/extend-expect';
import UsersTable from '../ponents/users/UserTable';
jest.mock('api', () => ({ // Mocking fetch user API call
fetchUsers: jest.fn(() =>
Promise.resolve(
Array.from({ length: 192 }, (_, i) => ({
id: i + 1,
fullName: `User ${i + 1}`,
email: `user${i + 1}@example.`,
}))
)
),
}));
test('Test #1: Count Users', async () => {
render(
<Router>
<UsersTable />
</Router>
);
// Waiting for the rows to rendered including the header row
await waitFor(() => {
expect(screen.getAllByRole('row').length).toBe(193);
});
});
This will guarantee asynchronous rendering and avoid querying before the data is available.
本文标签: javascriptHow to get the elements from a table after all components are renderedStack Overflow
版权声明:本文标题:javascript - How to get the elements from a table after all components are rendered? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744676934a2619168.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论