Почему изменение модуля обновляет ссылку при вызове этого модуля из другого модуля, но не при вызове из самого себя?
"В ES6 импорт - это оперативные представления только для чтения для экспортируемых значений" .
Когда вы импортируете модуль ES6, вы по существу получаете представление в реальном времени о том, что экспортируется этим модулем.
Оперативное представление может быть видоизменено, и любой код, который импортирует динамическое представление экспорта модуля, увидит мутацию.
Вот почему ваш тест работает, когда alpha
и beta
находятся в двух разных модулях. Тест изменяет динамическое представление модуля beta
, и поскольку модуль alpha
использует динамическое отображение модуля beta
, он автоматически использует фиктивную функцию вместо оригинальной.
С другой стороны, в приведенном выше коде alpha
и beta
находятся в одном модуле, а alpha
вызывает beta
напрямую . alpha
не не использует просмотр в реальном времени модуля, поэтому, когда тест изменяет просмотр в реальном времени модуля, он не действует.
В качестве дополнительного вопроса - в этом примере я изменяю модуль, напрямую переназначая свойства. Правильно ли я понимаю, что использование шутливой функциональности будет по существу делать то же самое?
Есть несколько способов издеваться над вещами, используя Jest
.
Одним из способов является использование jest.spyOn
, которое принимает объект и имя метода, а заменяет метод объекта шпионом, который вызывает оригинальный метод .
Распространенный способ использования jest.spyOn
состоит в том, чтобы передать его в режиме реального времени модуля ES6 в качестве объекта, который изменяет динамическое представление модуля.
Так что да, насмешливо, передавая в режиме реального времени модуль ES6 чему-то вроде jest.spyOn
(или spyOn
из Jasmine
или sinon.spy
из Sinon
и т. Д.) Изменяет динамическое представление модуля по существу так же, как и непосредственное изменение динамического просмотра модуля, как вы делаете в приведенном выше коде.
Насколько я знаю, во время тестирования этого модуля нет способа макетировать одну функцию в модуле, о чем говорит этот шутливый выпуск github. То, что я хочу знать, - вот почему.
На самом деле, возможно .
«Модули ES6 поддерживают циклические зависимости автоматически» , что означает, что динамическое представление модуля можно импортировать в сам модуль .
Пока alpha
вызывает beta
, используя динамическое отображение модуля, в котором определено beta
, тогда во время теста beta
может быть подвергнуто фиктивному воздействию. Это работает, даже если они определены в одном модуле:
import * as indexModule from './index' // import the live view of the module
export function alpha(n) {
return `${n}${indexModule.beta(n)}${n}`; // call beta using the live view of the module
}
export function beta(n) {
return new Array(n).fill(0).map(() => ".").join("");
}