Aller au contenu principal
Version: 25.x

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 :

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;
};

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('http://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 le helper 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.