Evitar mocks de módulos
Jest te permite simular módulos completos en tus pruebas, o que puede ser útil para probar si tu código está convocando correctamente las funciones de ese módulo. Sin embargo, a veces puede que quieras usar parte de un modulo mock en tus archivos de test. En ese caso, es necesario que accedas a la implementación original y no la implementación mock.
Considera escribir un test para la función crearUsuario
:
import fetch from 'node-fetch';
export const createUser = async () => {
const response = await fetch('https://website.com/users', {method: 'POST'});
const userId = await response.text();
return userId;
};
Tu test querrá ocupar un mock para la función fetch
, para que sepamos que ha sido llamada sin que en realidad haga una llamada en la red. Sin embargo, también necesitaras crear un mock para el valor que regresa fetch
con una Response
(envuelta en una Promise
), ya que nuestra función la ocupa para obtener el Id del usuario creado. De modo que inicialmente escribirías un test como el siguiente:
jest.mock('node-fetch');
import fetch, {Response} from 'node-fetch';
import {createUser} from './createUser';
test('createUser calls fetch with the right args and returns the user id', async () => {
fetch.mockReturnValue(Promise.resolve(new Response('4')));
const userId = await createUser();
expect(fetch).toHaveBeenCalledTimes(1);
expect(fetch).toHaveBeenCalledWith('https://website.com/users', {
method: 'POST',
});
expect(userId).toBe('4');
});
Sin embargo, te encontrarías con que la función createUser
fallaría, arrojando el error TypeError: respuesta.text is not a function
(Error de Tipo: respuesta.text no es una función). Esto es porque la clase Response
que importaste de node-fetch
ha sido sustituida por un mock (por la llamada a jest.mock
al principio del archivo test), así que no se comporta de la manera esperada.
Para evitar problemas como este, Jest proporciona la función jest.requireActual
. Para hacer que la prueba anterior funcione, haz los siguientes cambios a las importaciones en el archivo test:
// ANTES
jest.mock('node-fetch');
import fetch, {Response} from 'node-fetch';
// DESPUÉS
jest.mock('node-fetch');
import fetch from 'node-fetch';
const {Response} = jest.requireActual('node-fetch');
Esto permite que el archivo test importe el objeto Response
real de node-fetch
, en lugar de una versión mock. Esto significa que la prueba pasará correctamente.