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. Entretanto, as vezes você deseja usar partes do módulo mockado em seus arquivo de teste, nesse caso você precisa acessar a implementação original, ao invés de uma versão mockada.
Considere escrever um caso de testes para a função createUser
:
// createUser.js
import fetch from 'node-fetch';
export const createUser = async () => {
const response = await fetch('http://website.com/users', {method: 'POST'});
const userId = await response.text();
return userId;
};
Seu teste provavelm, ente irá "mockar" (mock) a função fetch
para que possamos ter certeza que esta será chamada sem realmente fazer um request ao endpoint. Contudo, você também precisará "mockar" o valor de retorno da função fetch
com uma Response
(encapsulada em uma Promise
). Então você pode inicialmente tentar escrever um teste como este:
jest.mock('node-fetch');
import fetch, {Response} from 'node-fetch';
import {createUser} from './createUser';
test('createUser chama a busta com os argumentos corretos e retorna o id do usuário', async () => {
fetch.mockReturnValue(Promise.resolve(new Response('4')));
const userId = await createUser();
expect(fetch).toHaveBeenCalledTimes(1);
expect(fetch).toHaveBeenCalledWith('http://website.com/users', {
method: 'POST',
});
expect(userId).toBe('4');
});
Se você rodar este teste você verá que a função createUser
falhará, disparando a excessão: TypeError: response.text is not a function
. Isto porque o Response
que você importou de node-fetch
foi "mockado" (através do script jest.mock
chamado no começo do arquivo) então não se comporta mais como deveria.
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';
// DEPOIS
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.