Смоделируйте весь модуль, но сохраните исходную логику модуля. Подобно поведению jest.spyOn по умолчанию, когда вызывается исходный метод.
Использование jest.mock позволяет выполнять необходимые утверждения, но не выполняет исходную логику, и иногда я хочу, чтобы эта логика выполнялась.
Использование jest.spyOn допускает утверждение и может выполнять исходную логику, но только для именованных экспортов модуля, что обычно полезно, но не тогда, когда метод экспортируется по умолчанию или как в приведенном ниже примере кода.
// moduleToMock.js
function doSomething(..args) {...}
doSomething.myWay = function myWay(...args) {...}
module.exports = doSomething
// moduleUsingModuleToMock.js
const doSomething = require('moduleToMock')
function doManyThings() {
doSomething(...)
doSomething.myWay(...)
}
module.exports = {
doManyThings,
}
// moduleUsingModuleToMock.test.js
// --
// some way to mock `moduleToMock` that still executes original logic
// --
const doSomething = require('moduleUsingModuleToMock')
it('correctly does many things', () => {
doManyThings()
expect(doSomething).toBeCalledWith(...)
expect(doSomething.myWay).toBeCalledWith(...)
})
Может я что-то простое упустил, но пока ни документы, ни гугл фу результатов не дали.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Невозможно издеваться над модулем и шпионить за его методами. Причина в том, что шутка действительно заменяет модуль макетом.
Извините, пропустил часть с выполнением исходной логики
сейчас делаю так
jest.mock('./somepath', () => (
Object.fromEntries(
Object.entries(jest.requireActual('./somepath'))
.map(([key, value]) => [key, jest.fn(value)])
)
))
это заставляет модуль сохранять исходную реализацию, но, поскольку все экспорты завернуты в jest.fn, теперь их можно имитировать с другой реализацией в каждом конкретном тесте.
Это возникало достаточно часто, поэтому я просто решил написать свою собственную библиотеку для создания автоматических макетов модулей, которые сохраняют исходную реализацию, но могут быть переопределены, как jest.spyOn.
import * as mock from "jest-mock-module";
mock.extend(jest); // optionally extend jest to use the "jest.spy" syntax
jest.spy("src/moduleToMock"); // Placed before other imports like "jest.mock".
import moduleToMock from "src/moduleToMock";
import moduleToTest from "src/moduleToTest";
it("does a thing", () => {
moduleToTest.callFunctionThatUsesModuleToMock();
expect(moduleToMock.usedFunction).toHaveBeenCalledTimes(1);
});
Я не думаю, что это выполняет логику исходного модуля, он просто предоставляет издевательский интерфейс.
jest.spyOn(module, 'methodName')по-прежнему выполняет исходную логику метода, а также предоставляет фиктивный интерфейс, я ищу эквивалент уровня модуля.