Testando componente lazy load React Suspense com Jest, React Testing Library e Typescript
- Publicado em: 03/06/2022
Já se deparou com o erro abaixo?
console.error
Warning: A suspended resource finished loading inside a test, but the event was not wrapped in act(...).
When testing, code that resolves suspended data should be wrapped into act(...):
act(() => {
/* finish loading suspended data */
});
/* assert on the output */
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
...
TestingLibraryElementError: Unable to find an element by: [data-testid="error"]
Bem genérico, certo? Mas se você estiver utilizando Lazy
e Suspense
para carregar seus componentes, talvez os próximos exemplos sejam úteis.
Tecnologias e versões
"dependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0",
"react-router-dom": "^6.3.0",
"styled-components": "^5.3.5",
},
"devDependencies": {
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.1.1",
"@testing-library/react-hooks": "^8.0.0",
"@testing-library/user-event": "^14.1.1",
"jest": "27.5.1",
"ts-jest": "^27.1.4",
"typescript": "^4.6.3",
}
Os Componentes
Home
import * as S from './style';
const Error = () => {
return (
<S.Container data-testid="home">
<S.Content>
<p>Home</p>
</S.Content>
</S.Container>
);
};
export default Error;
Error
import * as S from './style';
const Error = () => {
return (
<S.Container data-testid="error">
<S.Content>
<p>Essa página não foi encontrada</p>
</S.Content>
</S.Container>
);
};
export default Error;
App
import { lazy, Suspense } from 'react';
import { Routes, Route } from 'react-router-dom';
import { Loader } from 'components';
import * as S from './style';
const Home = lazy(() => import('containers/Home'));
const Error = lazy(() => import('containers/Error'));
const App = () => {
return (
<S.Container data-testid="app">
<Routes>
<Route path="/error" element={<Error />} />
<Route
path="/home"
element={
<Suspense fallback={<Loader />}>
<Home />
</Suspense>
}
/>
<Route path="*" element={<Error />} />
</Routes>
</S.Container>
);
};
export default App;
O teste
import { render, waitFor } from 'commons/utils/test';
import { createMemoryHistory } from 'history';
import { Router } from 'react-router-dom';
import App from './';
describe('[Containers] App', () => {
interface ISetup {
url: string;
}
const setup = async ({ url }: ISetup) => {
const history = createMemoryHistory();
history.push(url);
const utils = render(
<Router location={history.location} navigator={history}>
<App />
</Router>,
);
return {
...utils,
};
};
test('should render Error page', async () => {
const { getByTestId } = await setup({ url: '/xablau' });
await waitFor(() => expect(getByTestId('error')).toBeInTheDocument());
});
});