Gabriel Jiménez | Hace 9 días
En este artículo, abordaremos como conectar nuestra aplicación React sin utilizar una API real. En su lugar, simularemos una comunicación una API ficticia. Utilizaremos herramientas como Jest, React Testing Library y Nock para lograrlo.
Al final del artículo, serás capas de simular tu API con data dummy.
Nock es un librería para simular un servidor HTTP. Esto quiere decir que, solo se enfoca en la respuesta que esperamos al enviar cierta data al Backend. Por ejemplo, cuando creamos un usuario, enviamos todo la información —nombre, email, contraseña— al backend. El backend la recibe, procesa y nos devuelve una respuesta, ya sea correcta o incorrecta.
Ahora que ya sabemos que es Nock, es importante conocer como se relaciona con Jest y React Testing Library.
Jest es un framework Javascript para escribir, ejecutar y evaluar nuestras pruebas. Nos da un kit de herramientas, técnicas y buenas prácticas para trabajar con las pruebas.
Si quieres saber más sobre Jest, tengo un artículo dedicado: Qué es Jest y cómo funciona con React
React Testing Library es una librería que ofrece una variedad de funciones, para facilitar trabajar nuestras pruebas con ReactJS.
Si quieres aprender más sobre React Testing Library, revisa mi artículo: Qué es React Testing Library y cómo funciona con Jest
Para este ejemplo práctico, supongamos que necesitamos mostrar información de algunos usuarios de Github.
Github ofrece un API “publica”. Lo pongo entre comillas porque aunque no es necesario autentificarse si excedes cierto limite de peticiones nos devolverá un mensaje “API rate limit exceded”.
Puedes intentar refrescando la página varias veces por ti mismo. Obtendrás una respuesta como la siguiente:
https://api.github.com/users/octocat // Output { login: "octocat", id: 583231, node_id: "MDQ6VXNlcjU4MzIzMQ==", avatar_url: "https://avatars.githubusercontent.com/u/583231?v=4", gravatar_id: "", url: "https://api.github.com/users/octocat", html_url: "https://github.com/octocat", followers_url: "https://api.github.com/users/octocat/followers", following_url: "https://api.github.com/users/octocat/following{/other_user}", gists_url: "https://api.github.com/users/octocat/gists{/gist_id}", starred_url: "https://api.github.com/users/octocat/starred{/owner}{/repo}", subscriptions_url: "https://api.github.com/users/octocat/subscriptions", organizations_url: "https://api.github.com/users/octocat/orgs", repos_url: "https://api.github.com/users/octocat/repos", events_url: "https://api.github.com/users/octocat/events{/privacy}", received_events_url: "https://api.github.com/users/octocat/received_events", type: "User", user_view_type: "public", site_admin: false, name: "The Octocat", company: "@github", blog: "https://github.blog", location: "San Francisco", email: null, hireable: null, bio: null, twitter_username: null, public_repos: 8, public_gists: 8, followers: 20740, following: 9, created_at: "2011-01-25T18:44:36Z", updated_at: "2025-10-30T16:07:45Z" }
Ahora bien, si trabajamos directamente sobre nuestras pruebas, las peticiones gratuitas se nos terminaran fácilmente y tendremos que autentificarnos. La autentificación puede tener sus propias limitaciones.
Esto limita mucho trabajar con nuestras pruebas. Las pruebas no deben de depender de comunicarse con servicios externos, sino de ejecutarse de forma aislada.
Para facilitar la configuración de Jest y React Testing Library, usaremos Create React App.
Si quieres aprender a configurar Jest usando Vite, te invito a leer mi publicación: Qué es Jest y cómo funciona con React
Dicho esto, creemos nuestro proyecto usando Create React App.
npx create-react-app my-app cd my-app npm start
Una vez listo, instalemos Nock.
npm install --save-dev nock@13
NOTA: Las versiones recientes de nock utilizan APIs que Jest no incluye en su entorno de pruebas, ocasionando errores de compatibilidad.
Por último, instalemos “axios” para realizar nuestras peticiones al backend.
npm install axios
Listo, ya tenemos todo nuestro ambiente listo y configurado para nuestro ejemplo práctico.
Implementación de pruebas de nuestro ejemplo
Para nuestro ejemplo práctico, queremos destacar cuando un usuario tiene su cuenta privada usando el campo “user_view_type”.
Veamos como luce nuestro componente:
File: src/Github.jsx
1: import {useEffect, useState} from "react";
2: import axios from "axios";
3:
4: const Github = () => {
5: const [user, setUser] = useState(null)
6:
7: useEffect(() => {
8: axios.get('https://api.github.com/users/octocat')
9: .then(({ data }) => {
10: setUser(data)
11: })
12: }, [])
13:
14: if(!user) {
15: return null
16: }
17:
18: return (
19: <div>
20: {user.user_view_type === 'private' ? 'Cuenta privada' : 'Cuenta pública'}
21: <h1>Login: {user.login}</h1>
22: <img src={user.avatar_url} alt=""/>
23: </div>
24: )
25: }
26:
27: export default Github;
Analicemos
Línea 5
Creamos un estado para almacenar la información del usuario Git.
Línea 7:12
Hacemos una petición al API de Gihub para obtener la data del usuario “octocat”.
Línea 14:16
Si aún el backend no ha devuelto respuesta, no pintamos nada.
Línea 18:24
Renderizamos la información del usuario. Si es una cuenta privada, lo destacamos con un texto específico.
Bastante sencillo, ¿cierto? Así es, el detalle es cuando empezamos a tener muchas combinaciones como el caso de si es cuenta privada o publica.
Veamos como nock entra en acción para resolver esto.
File: src/Github.test.jsx
1: import {render, waitFor} from "@testing-library/react";
2: import Github from "./Github";
3: import nock from "nock";
4:
5: describe('Github', () => {
6: it('si es cuenta privada mostrar el título correcto', async () => {
7: nock('https://api.github.com')
8: .get('/users/octocat')
9: .reply(200, {
10: login: "octocat",
11: avatar_url: "https://avatars.githubusercontent.com/u/583231?v=4",
12: user_view_type: "private",
13: });
14:
15: render(<Github />)
16:
17: await waitFor(() => {
18: expect(document.body.textContent).toContain('Cuenta privada')
19: })
20: })
21: });
Analicemos
Línea 7:13
Le decimos a nock que, cuando se haga una petición al la url “https://api.github.com/users/octocat" la intercepte y nos devuelva una respuesta exitosa con un objeto específico.
Línea 15
Renderizamos el componente usando la función render de React Testing Library.
Línea 17:19
Comprobamos que el texto Cuenta privada se muestre cuando el usuario tenga el valor “private” en el campo “user_view_type”.
Antes de ejecutar la prueba es importante agregar un par de líneas a nuestro archivo de setupTests.js que configuramos con jest.
File: src/setupTests.js
1: // jest-dom adds custom jest matchers for asserting on DOM nodes.
2: // allows you to do things like:
3: // expect(element).toHaveTextContent(/react/i)
4: // learn more: https://github.com/testing-library/jest-dom
5: import '@testing-library/jest-dom';
6:
7: /**
8: * Si no mockeas Axios, Jest carga la versión Web, y eso causa errores.
9: * Mockearlo de esta forma obliga a Jest a usar la versión de Node.
10: */
11: jest.mock("axios", () => require("axios/dist/node/axios.cjs"));
12:
13: // Esto es clave: matar XMLHttpRequest antes de que axios se importe
14: // para que axios elija el adapter de Node (http) en vez de XHR (web).
15: if (typeof global.XMLHttpRequest !== 'undefined') {
16: // lo borramos del global
17: // (jsdom no lo necesita para que React Testing Library funcione)
18: delete global.XMLHttpRequest;
19: }
De forma muy general, estamos diciendo a Jest que utilice la versión de “node” de axios para realizar las peticiones al backend. De esta forma, nock puede interceptarlas.
Listo, ejecutemos la prueba:
npm test src/Github.test.jsx
// Output
PASS src/Github.test.jsx
Github
✓ si es cuenta privada mostrar el título correcto (21 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.544 s, estimated 1 s
Ran all test suites matching /src\/Github.test.jsx/I
Perfecto, nuestra prueba a pasado.
Ahora, vamos a ver que sucede si el usuario “octocat” no existe.
Nuestro componente debe mostrar el mensaje de error devuelto por el backend:
File: src/Github.jsx
. . .
4: const Github = () => {
5: const [user, setUser] = useState(null)
6: const [error, setError] = useState(null)
7:
8: useEffect(() => {
9: axios.get('https://api.github.com/users/octocat')
10: .then(({ data }) => {
11: setUser(data)
12: }).catch(({ response }) => {
13: setError(response.data.message);
14: })
15: }, [])
16:
17: if(error){
18: return <div>{error}</div>
19: }
. . .
Nock debe de devolver una petición fallida con un mensaje de error.
File: src/Github.test.jsx
. . .
22: it('mostrar mensaje de error si no existe el usuario', async () => {
23: nock('https://api.github.com')
24: .get('/users/octocat')
25: .reply(400, { message: "El usuario no existe" });
26:
27: render(<Github />)
28:
29: await waitFor(() => {
30: expect(document.body.textContent).toContain('El usuario no existe')
31: })
32: })
33: });
Analicemos
Línea 25
Estamos devolviendo una respuesta 400 y un mensaje cuando un usuario no existe.
Línea 20:31
Comprobamos que el mensaje devuelto por el backend se este mostrando correctamente.
Ejecutemos la prueba:
npm test src/Github.test.jsx
// Output
PASS src/Github.test.jsx
Github
✓ si es cuenta privada mostrar el título correcto (21 ms)
✓ mostrar mensaje de error si no existe el usuario (29 ms)
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 0.581 s, estimated 1 s
Ran all test suites matching /src\/Github.test.jsx/i.
Perfecto, nuestras dos pruebas han pasado correctamente.
Para poder trabajar nuestro frontend de forma aislada, podemos usar nock para simular la data devuelta por backend o algún servicio de terceros. Nock es una herramienta que trabaja perfectamente con Jest y React Testing Library. Sin embargo, existe otras formas para simular la data devuelta por el backend.
Si quieres aprender más sobre Testing en React, te recomiendo mi HUB: Testing en React, donde encontrarás todo lo necesario para adentrarte al mundo de pruebas. O si lo prefieres, tengo un libro sobre como trabajar con pruebas en React usando reales como el formulario de enlace de pago de Stripe.
Testing en React: Guía práctica con Jest y React Testing Library