Bypassing module mocks
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.
To get around problems like this, Jest provides the jest.requireActual
helper. To make the above test work, make the following change to the imports in the test file:
// 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');
This allows your test file to import the actual Response
object from node-fetch
, rather than a mocked version. This means the test will now pass correctly.