-
Notifications
You must be signed in to change notification settings - Fork 412
Closed
Description
@testing-library/jest-domversion: 5.11.9mswversion: 0.28.2nodeversion: 14.17.1react-testing-libraryversion: 11.2.5@material-ui/core: 4.11.3,@material-ui/data-grid: 4.0.0-alpha.19- axios: 0.21.1
Relevant code or config:
UsersTable.test.tsx
import UsersTable from './UsersTable';
import { render, screen, waitFor } from '../../test/setup';
import { server, rest } from '../../test/server';
describe('Testing UsersTable component', () => {
it('renders the component', async () => {
render(<UsersTable />);
await waitFor(() => {
const tableHeader = screen.getByRole('row', {
name: 'Id Email Company',
});
expect(tableHeader).toBeInTheDocument();
});
});
it('renders error message if not able to fetch models from server', async () => {
// Get back error message from server
server.use(
rest.get('http://localhost:9000/api/users', (req, res, ctx) => {
return res(
ctx.status(400),
ctx.json({ message: 'Access to account denied' })
);
})
);
render(<UsersTable />);
await waitFor(() => {
// Expect not find any rows in the table
const companyNameCells = screen.queryByText(/Rootit/i);
expect(companyNameCells).toBeNull();
// Expect alert message to pop up
const alertMessage = screen.getByText('Access to account denied');
expect(alertMessage).toBeInTheDocument();
});
});
it('renders models that are fetched from server in the table', async () => {
render(<UsersTable />);
const emailOneCell = await screen.findByText('test1@test.com');
const emailTwoCell = await screen.findByText('test2@test.com');
expect(emailOneCell).toBeDefined();
expect(emailTwoCell).toBeDefined();
});
});
mws setup
import { rest } from 'msw';
import { setupServer } from 'msw/node';
const users = [
{
id: 'abc',
email: 'test1@test.com',
company: 'Test',
},
{
id: 'def',
email: 'test2@test.com',
company: 'Test',
},
{
id: 'ghi',
email: 'test3@test.com',
company: 'Test',
},
{
id: 'jkl',
email: 'test4@test.com',
company: 'Test',
},
];
const handlers = [
rest.get('http://localhost:9000/api/users', (req, res, ctx) => {
return res(ctx.status(200), ctx.json(users));
}),
];
// This configures a request mocking server with the given request handlers
const server = setupServer(...handlers);
export { server, rest };
UsersTable.tsx
import { useCallback, useEffect, useRef, useState, useContext } from 'react';
import { DataGrid, GridColDef } from '@material-ui/data-grid';
import { Box } from '@material-ui/core';
import TableTooltip from '../../components/Tooltip/Tooltip';
import { useStyles } from './UsersTable.styles';
import { ActionTypes, AppContext } from '../../context/app-context';
import { ApiResult } from '../../api/ApiResultInterface';
import { ApiService } from '../../api/ApiSevice';
type User = {
id: string;
email: string;
company: string;
};
const UsersTable = () => {
const [users, setUsers] = useState<User[]>([]);
const classes = useStyles();
const { dispatch } = useContext(AppContext);
// Used to not update state if component is unmounted before data fetch is complete
let _isMounted = useRef(true);
const setAlert = useCallback(
(msg: string, status: number) => {
dispatch({
type: ActionTypes.SetAlertMessage,
payload: new ApiResult(msg, status),
});
dispatch({ type: ActionTypes.OpenAlertMessage, payload: true });
},
[dispatch]
);
useEffect(() => {
return () => {
_isMounted.current = false;
};
}, []);
useEffect(() => {
const fetchUsers = async () => {
try {
const response = await ApiService.getUsers();
// Do nothing if component has unmounted while fetching data
if (!_isMounted.current) {
return;
}
setUsers(response.data);
} catch (err) {
if (err.response) {
const status = err.response.status;
const error = err.response.data;
setAlert(error.message, status);
} else {
setAlert(err.message, 400);
}
}
};
fetchUsers();
}, [setAlert]);
// Table columns
const columns: GridColDef[] = [
{
field: 'id',
headerName: 'Id',
description: 'Id',
headerAlign: 'center',
align: 'center',
flex: 2,
renderCell: (cellParams) => {
return (
<TableTooltip title={cellParams.value as string}>
<div className={classes.cellText}>{cellParams.value}</div>
</TableTooltip>
);
},
renderHeader: (headerParams) => {
return (
<TableTooltip title={headerParams.colDef.description as string}>
<div className={classes.cellText}>
{headerParams.colDef.description}
</div>
</TableTooltip>
);
},
},
{
field: 'email',
description: 'Email',
headerName: 'Email',
headerAlign: 'center',
align: 'center',
flex: 2,
renderCell: (cellParams) => {
return (
<TableTooltip title={cellParams.value as string}>
<div className={classes.cellText}>{cellParams.value}</div>
</TableTooltip>
);
},
renderHeader: (headerParams) => {
return (
<TableTooltip title={headerParams.colDef.description as string}>
<div className={classes.cellText}>
{headerParams.colDef.description}
</div>
</TableTooltip>
);
},
},
{
field: 'company',
description: 'Company',
headerName: 'Company',
headerAlign: 'center',
align: 'center',
flex: 1,
renderCell: (cellParams) => {
return (
<TableTooltip title={cellParams.value as string}>
<div className={classes.cellText}>{cellParams.value}</div>
</TableTooltip>
);
},
renderHeader: (headerParams) => {
return (
<TableTooltip title={headerParams.colDef.description as string}>
<div className={classes.cellText}>
{headerParams.colDef.description}
</div>
</TableTooltip>
);
},
},
];
return (
<Box boxShadow={3} className={classes.usersTableContainer}>
<DataGrid
rows={users}
loading={users === []}
columns={columns}
pageSize={100}
className={classes.usersTable}
checkboxSelection={false}
localeText={{
footerRowSelected: () => '',
}}
/>
</Box>
);
};
export default UsersTable;
What happened:
Problem description:
I expected screen to find the fetched data in the DataGrid component but it does not. I have written other very similar tests with the same setup and they all pass so I do not understand why this one does not.
I console logged the response that I get back from the mocked axios call and I see the data. I know that the state is being updated but for some reason screen.findByText() does not find it.
Can you help me figure out why this is happening?
Metadata
Metadata
Assignees
Labels
No labels

