Как шпионить за экспортированной функцией по умолчанию с помощью Jest?

Предположим, у меня есть простой файл, экспортирующий функцию по умолчанию:

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

export default uniqueIdGenerator;

Который я бы использовал так:

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

Я хочу утверждать в своем тесте, что этот метод был вызван с сохранением исходной функциональности. Я бы сделал это с jest.spyOn, однако для этого требуется объект, а также имя функции в качестве параметров. Как это сделать по-чистому? Есть аналогичная проблема GitHub для jasmine для всех, кто заинтересован.


person thisismydesign    schedule 17.01.2019    source источник


Ответы (4)


В итоге я отказался от экспорта по умолчанию:

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

И тогда я мог бы использовать и шпионить это так:

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

Некоторые рекомендуют заключить их в константный объект и экспортировать . Я полагаю, вы также можете использовать класс для упаковки.

Однако, если вы не можете изменить класс, все еще есть (не очень приятное) решение:

import * as UniqueIdGenerator from './UniqueIdGenerator';
// ...
const spy = jest.spyOn(UniqueIdGenerator, 'default');
person thisismydesign    schedule 17.01.2019
comment
но это работает только тогда, когда он передается Babel через модули es6. Не будет работать на CommonJS - person Christopher Francisco; 27.08.2019

В некоторых случаях вам нужно имитировать импорт, чтобы иметь возможность отслеживать экспорт по умолчанию:

import * as fetch from 'node-fetch'

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

jest.spyOn(fetch, 'default')
person Janne Annala    schedule 23.09.2020

можно также смоделировать импорт и передать исходную реализацию как фиктивную реализацию, например:

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()
})
person alex.spri    schedule 24.11.2020

Мне помогло сочетание ответа Janne Annala и собственного решения OP. Все, что я хотел проверить, это то, что вспомогательный метод вызывается с правильными параметрами, поскольку я уже написал тест для вспомогательного метода, и это не имело никакого отношения к моему последующему тесту:

// myHelperMethod.js

export const myHelperMethod = (param1, param2) => { // do something with the params };
// someOtherFileUsingMyHelperMethod.js

import * as MyHelperMethod from '../myHelperMethod';


jest.mock('../myHelperMethod', () => ({
  myHelperMethod: jest.fn(),
}));

let myHelperMethodSpy = jest.spyOn(MyHelperMethod, 'myHelperMethod');

// ...
// some setup
// ...

test(() => {
  expect(myHelperMethodSpy).toHaveBeenCalledWith(param1, param2);
});
person AdamJB    schedule 27.04.2021
comment
Понижено, потому что это не решает суть исходного вопроса - как это сделать с экспортом по умолчанию - person Switch386; 03.06.2021
comment
Несмотря на то, что сами OP решили отказаться от экспорта по умолчанию в своем принятом ответе? - person AdamJB; 05.06.2021
comment
Это другой вопрос. ТАК так не работает - person Switch386; 05.06.2021