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.