Evitar mocks de módulos
Jest allows you to mock out whole modules in your tests, which can be useful for testing if your code is calling functions from that module correctly. 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
:
// crearUsuario.js
import fetch from 'node-fetch';
export const crearUsuario = async () => {
const respuesta = await fetch('http://sitio.com/usuarios', {method: 'POST'});
const idUsuario = await respuesta.text();
return idUsuario;
};
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 {crearUsuario} from './crearUsuario';
test('crearUsuario llama a fetch con los argumentos correctos y regresa el Id del usuario', async () => {
fetch.mockReturnValue(Promise.resolve(new Response('4')));
const idUsuario = await crearUsuario();
expect(fetch).toHaveBeenCalledTimes(1);
expect(fetch).toHaveBeenCalledWith('http://sitio.com/usuarios', {
method: 'POST',
});
expect(idUsuario).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.