Las pruebas Unitarias son muy importantes en el proceso de desarrollo de software, nos aseguran un funcionamiento correcto y evitan regresiones en nuestro código.
Hoy vamos a aprender a crear pruebas unitarias con Jest e integrarlas en React Native con Expo.
NUEVAS INSTRUCIONES:
Necesitamos tener la última versión de React en nuestro proyecto, en mi caso me pide React 18.3.1
Si usas typescript instalar los types y si no no.
npx expo install -- --save-dev jest-expo jest @types/jest
Ahora abrimos packacge.json y añadimos este comando dentro de scripts:
"test": "jest --watchAll"
Añadimos este código al final:
"jest": { "preset": "jest-expo", "transformIgnorePatterns": [ "node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@sentry/react-native|native-base|react-native-svg)" ], testMatch: [ '**/?(*.)+(test).tsx', // Archivos .test.tsx '**/?(*.)+(test).js', // Archivos .test.js '**/?(*.)+(test).ts', // Archivos .test.ts (en caso de que uses solo TypeScript) '**/?(*.)+(test).jsx', // Archivos .test.jsx '**/?(*.)+(test).js' // Archivos .test.js ] },
Otra opción mas recomendada es crear el archivo jest.config.js y añadir el código en ese archivo en vez de package.json
module.exports = { preset: 'jest-expo', transformIgnorePatterns: [ 'node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@sentry/react-native|native-base|react-native-svg)' ], testMatch: [ '**/?(*.)+(test).tsx', // Archivos .test.tsx '**/?(*.)+(test).js', // Archivos .test.js '**/?(*.)+(test).ts', // Archivos .test.ts (en caso de que uses solo TypeScript) '**/?(*.)+(test).jsx', // Archivos .test.jsx '**/?(*.)+(test).js' // Archivos .test.js ] };
Instalamos las librerías de testing con react native
npx expo install -- --save-dev @testing-library/react-native
Si necesitamos borrar chache de jest:
npx jest --clearCache
Crear tus pruebas unitarias
Crea un archivo con extensión .test.tsx
o .test.js
junto al componente que quieras probar o en una carpeta dedicada, como __tests__/
.
Ejemplo: Prueba para un botón simple Si tienes un componente Button.tsx
:
import React from 'react'; import { Button } from 'react-native'; const MyButton = ({ onPress, title }: { onPress: () => void; title: string }) => ( return ( <Button onPress={onPress} title={title} />); ); export default MyButton ;
Y ahora debemos crear su test Button.test.tsx
import { render, fireEvent } from '@testing-library/react-native'; test('Button renders correctly and responds to press', () => { const mockPressHandler = jest.fn(); const { getByText } = render(<MyButton onPress={mockPressHandler} title="Press me" />); // Verificar si el botón aparece expect(getByText('Press me')).toBeTruthy(); // Simular un clic fireEvent.press(getByText('Press me')); expect(mockPressHandler).toHaveBeenCalledTimes(1); });
Ejecutar las pruebas
Corre los tests usando el comando:
npm test
Esto ejecutará Jest y mostrará el resultado de las pruebas.
Añadir coverage
Para activar coverage, vamos al archivo jest.config.js y añadimos:
collectCoverage: true, coverageDirectory: './coverage/', coverageReporters: ['text', 'lcov'], collectCoverageFrom: [ 'src/**/*.{ts,tsx,js,jsx}', // Archivos para los cuales se recogerá la cobertura '!src/**/*.d.ts' // Excluye archivos de definición ]
6. Pruebas para hooks o lógica compleja
Si tienes lógica separada en hooks o funciones auxiliares, utiliza jest
para probarlos:
Ejemplo: Hook simple Si tienes un hook useCounter.ts
:
import { useState } from 'react'; export const useCounter = () => { const [count, setCount] = useState(0); const increment = () => setCount((prev) => prev + 1); return { count, increment }; };
Prueba del hook:
import { renderHook, act } from '@testing-library/react-hooks'; import { useCounter } from './useCounter'; test('useCounter works correctly', () => { const { result } = renderHook(() => useCounter()); // Verificar estado inicial expect(result.current.count).toBe(0); // Ejecutar incremento act(() => { result.current.increment(); }); // Verificar el nuevo valor expect(result.current.count).toBe(1); });
Ingeniero en Informática, me encanta crear cosas o arreglarlas y darles una nueva vida. Escritor y poeta. Más de 20 APPs publicadas y un libro en Amazon.