34
votes

Comment espionner une fonction exportée par défaut avec Jest?

Supposons que j'ai un simple fichier exportant une fonction par défaut:

import uniqueIdGenerator from './UniqueIdGenerator';
// ...
uniqueIdGenerator();

Ce que j'utiliserais comme ceci:

// UniqueIdGenerator.js
const uniqueIdGenerator = () => Math.random().toString(36).substring(2, 8);

export default uniqueIdGenerator;

Je veux affirmer dans mon test que cette méthode a été appelée tout en conservant la fonctionnalité d'origine. Je ferais cela avec jest.spyOn cependant, il nécessite un objet ainsi qu'un nom de fonction en tant que paramètres. Comment pouvez-vous faire cela de manière propre? Il existe un problème similaire sur GitHub pour le jasmine pour toute personne intéressée.


0 commentaires

3 Réponses :


43
votes

J'ai fini par abandonner l'exportation par défaut:

import * as UniqueIdGenerator from './UniqueIdGenerator';
// ...
const spy = jest.spyOn(UniqueIdGenerator, 'default');

Et puis je pourrais l'utiliser et l'espionner comme ceci:

import * as UniqueIdGenerator from './UniqueIdGenerator';
// ...
const spy = jest.spyOn(UniqueIdGenerator, 'uniqueIdGenerator');

Certains recommandent de les envelopper dans un objet const et de l'exporter. Je suppose que vous pouvez également utiliser une classe pour l'emballage.

Cependant, si vous ne pouvez pas modifier la classe, il y a toujours une solution (pas si gentille):

// UniqueIdGenerator.js
export const uniqueIdGenerator = () => Math.random().toString(36).substring(2, 8);


1 commentaires

mais cela ne fonctionne que lorsqu'il est transpilé par babel via les modules es6. Ne fonctionnera pas sur CommonJS



1
votes

Dans certains cas, vous devez vous moquer de l'importation pour pouvoir espionner l'exportation par défaut:

import * as fetch from 'node-fetch'

jest.mock('node-fetch', () => ({
  default: jest.fn(),
}))

jest.spyOn(fetch, 'default')


0 commentaires

0
votes

on pourrait également se moquer de l'importation et passer l'implémentation d'origine comme implémentation fictive, comme:

import uniqueIdGenerator from './UniqueIdGenerator'; // this import is a mock already

jest.mock('./UniqueIdGenerator.js', () => {
  const original = jest. requireActual('./UniqueIdGenerator')
  return {
     __esModule: true,
     default: jest.fn(original.default)
  }
})

test(() => {
  expect(uniqueIdGenerator).toHaveBeenCalled()
})


0 commentaires