Contourner les mocks de modules
Cette page a été traduite par PageTurner AI (bêta). Non approuvée officiellement par le projet. Vous avez trouvé une erreur ? Signaler un problème →
Jest vous permet de simuler des modules entiers dans vos tests, ce qui est utile pour vérifier si votre code appelle correctement leurs fonctions. Cependant, il arrive qu'on veuille utiliser certaines parties originales d'un module mocké dans le fichier de test lui-même, nécessitant ainsi d'accéder à l'implémentation réelle plutôt qu'à sa version simulée.
Prenons l'exemple d'un test à écrire 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 pour s'assurer de son appel sans déclencher de requête réseau réelle. Mais vous devrez aussi simuler la valeur de retour de fetch avec un objet Response (dans une Promise), car notre fonction l'utilise pour récupérer l'ID de l'utilisateur créé. Votre première approche pourrait ressembler à ceci :
jest.mock('node-fetch');
import fetch, {Response} from 'node-fetch';
import {createUser} from './createUser';
test('createUser calls fetch with the right args and returns the user id', 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');
});
Or, en exécutant ce test, la fonction createUser échouerait en générant l'erreur : TypeError: response.text is not a function. Cela s'explique parce que la classe Response importée depuis node-fetch a été mockée (à cause de l'appel jest.mock en tête du fichier) et ne se comporte donc plus normalement.
Pour contourner ce genre de problèmes, Jest fournit l'utilitaire jest.requireActual. Pour corriger le test précédent, modifiez les imports comme suit :
// BEFORE
jest.mock('node-fetch');
import fetch, {Response} from 'node-fetch';
// AFTER
jest.mock('node-fetch');
import fetch from 'node-fetch';
const {Response} = jest.requireActual('node-fetch');
Cela permet au fichier de test d'importer l'objet Response réel depuis node-fetch plutôt qu'une version simulée. Le test passera alors correctement.