Estoy trabajando con un componente simple que tiene un efecto secundario. Mi prueba pasa, pero recibo la advertencia Warning: An update to Hello inside a test was not wrapped in act(...).
.
Tampoco sé si waitForElement
es la mejor manera de escribir esta prueba.
mi componente
export default function Hello() { const [posts, setPosts] = useState([]); useEffect(() => { const fetchData = async () => { const response = await axios.get('https://jsonplaceholder.typicode.com/posts'); setPosts(response.data); } fetchData(); }, []); return ( <div> <ul> { posts.map( post => <li key={post.id}>{post.title}</li> ) } </ul> </div> ) }
Mi prueba de componentes
import React from 'react'; import {render, cleanup, act } from '@testing-library/react'; import mockAxios from 'axios'; import Hello from '.'; afterEach(cleanup); it('renders hello correctly', async () => { mockAxios.get.mockResolvedValue({ data: [ { id: 1, title: 'post one' }, { id: 2, title: 'post two' }, ], }); const { asFragment } = await waitForElement(() => render(<Hello />)); expect(asFragment()).toMatchSnapshot(); });
Respuesta actualizada:
Consulte el comentario de @mikaelrs a continuación.
No es necesario esperar o esperarElemento. Simplemente puede usar los selectores findBy* que devuelven una promesa que se puede esperar. por ejemplo, esperar findByTestId('lista');
Respuesta en desuso:
Use waitForElement
es una forma correcta, de los documentos:
Espere hasta que se resuelva la promesa de solicitud de
get
simulada y el componente llame a setState y vuelva a procesar.waitForElement
espera hasta que la devolución de llamada no arroje un error
Aquí está el ejemplo de trabajo para su caso:
index.jsx
:
import React, { useState, useEffect } from 'react'; import axios from 'axios'; export default function Hello() { const [posts, setPosts] = useState([]); useEffect(() => { const fetchData = async () => { const response = await axios.get('https://jsonplaceholder.typicode.com/posts'); setPosts(response.data); }; fetchData(); }, []); return ( <div> <ul data-testid="list"> {posts.map((post) => ( <li key={post.id}>{post.title}</li> ))} </ul> </div> ); }
index.test.jsx
:
import React from 'react'; import { render, cleanup, waitForElement } from '@testing-library/react'; import axios from 'axios'; import Hello from '.'; jest.mock('axios'); afterEach(cleanup); it('renders hello correctly', async () => { axios.get.mockResolvedValue({ data: [ { id: 1, title: 'post one' }, { id: 2, title: 'post two' }, ], }); const { getByTestId, asFragment } = render(<Hello />); const listNode = await waitForElement(() => getByTestId('list')); expect(listNode.children).toHaveLength(2); expect(asFragment()).toMatchSnapshot(); });
Resultados de las pruebas unitarias con una cobertura del 100 %:
PASS stackoverflow/60115885/index.test.jsx ✓ renders hello correctly (49ms) -----------|---------|----------|---------|---------|------------------- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s -----------|---------|----------|---------|---------|------------------- All files | 100 | 100 | 100 | 100 | index.jsx | 100 | 100 | 100 | 100 | -----------|---------|----------|---------|---------|------------------- Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 1 passed, 1 total Time: 4.98s
index.test.jsx.snapshot
:
// Jest Snapshot v1 exports[`renders hello correctly 1`] = ` <DocumentFragment> <div> <ul data-testid="list" > <li> post one </li> <li> post two </li> </ul> </div> </DocumentFragment> `;
código fuente: https://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/60115885
Para mí, la solución fue esperar a waitForNextUpdate
it('useMyHook test', async() => { const { result, waitForNextUpdate } = renderHook(() => useMyHook(), ); await waitForNextUpdate() expect(result.current).toEqual([]) }