Pruebas Unitarias con Jest en React Native y Expo

Tiempo de lectura: 2 minutos

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.

Torre Guía - Pexels

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);
});

Deja un comentario