web-dev-qa-db-fra.com

Jest moquant les exportations par défaut - nécessite vs import

J'ai vu des questions se référer à la moquerie des exportations par défaut avec plaisanterie ici, mais je ne pense pas que cela ait déjà été posé:

Lors de la simulation de l'exportation par défaut d'une dépendance d'un module en cours de test, la suite de tests ne s'exécute pas si le module importe la dépendance avec l'instruction d'importation ES6, indiquant TypeError: (0 , _dependency.default) is not a function Elle réussit cependant si le module utilise à la place un appel require().default.

À ma connaissance, import module from location Se traduit directement par const module = require(location).default, donc je suis très confus pourquoi cela se produit. Je préfère garder mon style de code cohérent et ne pas utiliser l'appel require dans le module d'origine.

Y a-t-il un moyen de le faire?

Fichier de test avec maquette:

import './modules.js';
import dependency from './dependency';

jest.mock('./dependency', () => {
   return {
      default: jest.fn()
   };
});

// This is what I would eventually like to call
it('calls the mocked function', () => {
   expect(dependency).toHaveBeenCalled();
});

Dependency.js

export default () => console.log('do something');

module.js (ne fonctionne pas)

import dependency from './dependency.js';
dependency();

module.js (travail)

const dependency = require('./dependency.js').default;
dependency();
9
Anna Melzer

Vous pouvez utiliser soit es6 import ou require js pour importer vos fichiers js dans vos tests jest.

Lors de l'utilisation de es6 import vous devez savoir que jest essaie de résoudre toutes les dépendances et appelle également le constructeur de la classe que vous importez. Au cours de cette étape, vous ne pouvez pas vous moquer . La dépendance doit être résolue avec succès, puis vous pouvez procéder à des simulations.

Je dois également ajouter que, comme on peut le voir ici jest par défaut hisse tous les jest.mocks en haut du fichier afin que l'ordre dans lequel vous placez vos importations n'ait pas vraiment d'importance.

Votre problème est cependant différent. Votre fonction de simulation suppose que vous avez inclus votre fichier js à l'aide de require js.

jest.mock('./dependecy', () => {
   return {
      default: jest.fn()
   };
});

Lorsque vous importez un fichier à l'aide de require js, voici sa structure:

enter image description here

Donc, en supposant que j'ai importé ma classe appelée "Test" en utilisant require js, et il a une méthode appelée "doSomething" Je pourrais l'appeler dans mon test en faisant quelque chose comme:

const test = require('../Test');
test.default.doSomething();

Lors de son importation à l'aide de es6 import, vous devez cependant procéder différemment. En utilisant le même exemple:

import Test from '../Test';
Test.doSomething();

EDIT: Si vous souhaitez utiliser es6 import changez votre fonction de simulation en:

jest.mock('./dependecy', () => jest.fn());
10
Sotiris Kiritsis