He hecho un componente ficticio con el propósito de ilustrar. Encuentre el código a continuación-
Obtener.js
import React from "react"; import { useFetch } from "./useFetch"; const FetchPost = () => { const { toShow, dummyAPICall } = useFetch(); return toShow ? ( <> <button onClick={dummyAPICall} data-testid="fetch-result"> Fetch </button> </> ) : null; }; export { FetchPost };usarFetch.js
import { useState } from "react"; const useFetch = () => { const [toShow, setToShow] = useState(true); const dummyAPICall = () => { fetch("https://jsonplaceholder.typicode.com/todos/1") .then((response) => response.json()) .then((json) => { setToShow(false); }) .catch(() => { setToShow(true); }); }; return { toShow, setToShow, dummyAPICall, }; }; export { useFetch };Quiero hacer una afirmación aquí, que al hacer clic en el botón Fetch , mi componente Fetch no debería mostrarse en la pantalla, por lo que, usando React Testing Library, estoy escribiendo el caso de prueba de esta manera:
import { fireEvent, render, screen } from "@testing-library/react"; import { FetchPost } from "../Fetch"; import { useFetch } from "../useFetch"; jest.mock("../useCounter"); describe("Use Fetch tests", () => { it("Should fetch results and show/hide component", async () => { useFetch.mockImplementation(() => { return { toShow: true, dummyAPICall: jest.fn() }; }); render(<FetchPost></FetchPost>); expect(screen.getByText(/fetch/i)).toBeInTheDocument(); fireEvent.click(screen.getByTestId("fetch-result")); await waitFor(() => expect(screen.queryByText(/fetch/i)).not.toBeInTheDocument() ); }); });Mi afirmación:
expect(screen.getByText(/fetch/i)).not.toBeInTheDocument();está fallando porque el componente todavía está presente. ¿Cómo puedo modificar mi caso de prueba para manejar esto?
El efecto secundario de E/S de la red simulada es mejor que el gancho useFetch simulado. Parece que se olvidó de importar la función de ayuda waitFor del paquete RTL.
Hay dos opciones para simular los efectos secundarios de E/S de la red.
global.fetch = jest.fn() , no es necesario instalar un paquete adicional ni configurarlo.Voy a usar la opción 2 para resolver tu pregunta.
P.ej
fetch.jsx :
import React from 'react'; import { useFetch } from './useFetch'; const FetchPost = () => { const { toShow, dummyAPICall } = useFetch(); return toShow ? ( <> <button onClick={dummyAPICall} data-testid="fetch-result"> Fetch </button> </> ) : null; }; export { FetchPost }; useFetch.js :
import { useState } from 'react'; const useFetch = () => { const [toShow, setToShow] = useState(true); const dummyAPICall = () => { fetch('https://jsonplaceholder.typicode.com/todos/1') .then((response) => response.json()) .then((json) => { setToShow(false); }) .catch(() => { setToShow(true); }); }; return { toShow, setToShow, dummyAPICall }; }; export { useFetch }; fetch.test.jsx :
import React from 'react'; import { FetchPost } from './fetch'; import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import '@testing-library/jest-dom/extend-expect'; describe('Use Fetch tests', () => { it('Should fetch results and show/hide component', async () => { const mResponse = { json: jest.fn() }; global.fetch = jest.fn().mockResolvedValueOnce(mResponse); render(<FetchPost />); expect(screen.getByText(/fetch/i)).toBeInTheDocument(); fireEvent.click(screen.getByTestId('fetch-result')); await waitFor(() => expect(screen.queryByText(/fetch/i)).not.toBeInTheDocument()); }); });Resultado de la prueba:
PASS examples/70666232/fetch.test.jsx (12.699 s) Use Fetch tests ✓ Should fetch results and show/hide component (51 ms) -------------|---------|----------|---------|---------|------------------- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s -------------|---------|----------|---------|---------|------------------- All files | 93.75 | 100 | 83.33 | 93.75 | fetch.jsx | 100 | 100 | 100 | 100 | useFetch.js | 90 | 100 | 80 | 90 | 12 -------------|---------|----------|---------|---------|------------------- Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total Time: 14.38 sversión del paquete:
"@testing-library/react": "^11.2.2", "@testing-library/jest-dom": "^5.11.6", "jest": "^26.6.3", "react": "^16.14.0"