Contournement des modules simulés
Jest vous permet de simuler des modules entiers dans vos tests, ce qui peut être utile pour vérifier si votre code appelle correctement les fonctions de ce module. Cependant, vous souhaitez parfois utiliser des parties d'un module simulé dans votre fichier de test, auquel cas vous souhaitez accéder à l'implémentation originale, plutôt qu'à une version simulée.
Considérons l'écriture d'un scénario de test pour cette fonction createUser
:
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;
};
Votre test devra simuler la fonction fetch
afin de s'assurer qu'elle est appelée sans effectuer la requête réseau. Cependant, vous devrez également simuler la valeur de retour de fetch
avec un Response
(enveloppé dans une Promesse
), car notre fonction l'utilise pour récupérer l'ID de l'utilisateur créé. Vous pouvez donc, dans un premier temps, essayer d'écrire un test comme celui-ci :
jest.mock('node-fetch');
import fetch, {Response} from 'node-fetch';
import {createUser} from './createUser';
test('createUser appelle fetch avec les bons arguments et retourne l\'ID de l\'utilisateur', 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');
});
Cependant, si vous exécutez ce test, vous constaterez que la fonction createUser
échoue, lançant l'erreur : TypeError : response.text is not a function
. Cela est dû au fait que la classe Response
que vous avez importée de node-fetch
a été simulée (en raison de l'appel jest.mock
en haut du fichier de test) et ne se comporte donc plus comme elle le devrait.
Pour contourner de tels problèmes, Jest fournit la fonction d'aide jest.requireActual
. Pour que le test ci-dessus fonctionne, apportez la modification suivante aux importations dans le fichier de test :
// AVANT
jest.mock('node-fetch');
import fetch, {Response} from 'node-fetch';
// APRES
jest.mock('node-fetch');
import fetch from 'node-fetch';
const {Response} = jest.requireActual('node-fetch');
Cela permet à votre fichier de test d'importer l'objet Response
réel de node-fetch
, plutôt qu'une version simulée. Cela signifie que le test va maintenant passer correctement.