Следите за импортированной функцией, которая вызывает другую функцию в Jest

Я пытаюсь шпионить за функцией, которая вызывается другой функцией, которая находится во внешнем файле и импортирована.

Funcs.spec.js:

import * as Funcs from './Funcs'
describe('funcA', () => {
    it('calls funcB', () => {
        jest.spyOn(Funcs, 'funcB')
        Funcs.funcA()
        expect(Funcs.funcB).toHaveBeenCalled()
    }
}

Funcs.js:

export const funcA = () => {
    funcB()
}
export const funcB = () => {}

По какой-то причине шпион не входит в сферу применения Funcs.js. Что я могу сделать, чтобы шпионить за funcB, чтобы я знал, что funcA вызвал его?

2 ответа

Решение

Только методы могут быть отслежены. Нет возможности шпионить за funcB если это называется прямо как funcB() в том же модуле.

Для того, чтобы экспортированная функция была шпионской или поддельной, funcA а также funcB должен находиться в разных модулях.

Это позволяет шпионить за funcB в переносимом модуле ES (объект модуля доступен только для чтения в собственном ESM):

import { funcB } from './b';

export const funcA = () => {
    funcB()
}

В связи с тем, что импорт модулей является представлениями модулей, это переносится в:

var _b = require('./b');

var funcA = exports.funcA = function funcA() {
    (0, _b.funcB)();
};

куда funcB метод привязан к _b объект модуля, так что за ним можно следить.

Проблема, которую вы описываете, упоминается в шутливой проблеме.

Возможное решение вашей проблемы (если вы хотите сохранить функции в одном и том же файле) - использовать CommonJS, рассмотрите следующий пример:

fns.js

exports.funcA = () => {
  exports.funcB();
};
exports.funcB = () => {};

fns.spec.js

const fns = require("./fns");

describe("funcA", () => {
  it("calls funcB", () => {
    fns.funcB = jest.fn();
    fns.funcA();
    expect(fns.funcB).toBeCalled();
  });
});
Другие вопросы по тегам