Я начну с настройки, прежде чем приступить к проблеме.Давайте начнем с базового файла, чьи именованные экспорты мы будем шпионить:
// fileA.js
export function bar() {}
export function foo() {}
И затем у нас будет два варианта классов, импортирующих их, один в стиле CommonJS, а другой в стиле ES6:
// es6Baz.js
import * as A from 'fileA'
export default class Baz {
callFoo() { A.foo(); }
}
// commonBaz.js
const A = require('fileA');
export default class Baz {
callFoo() { A.foo(); }
}
Затем аналогичным образом протестируйте файлы для этих двух вариантов:
// testEs6A.js
import Baz from 'es6Baz';
import * as A from 'fileA';
it('test', () => {
spyOn(A, 'foo');
const b = new Baz();
b.callFoo();
expect(A.foo).toHaveBeenCalled(); // this will fail
});
// testCommonA.js
import Baz from 'es6Baz';
const A = require('fileA');
it('test', () => {
spyOn(A, 'foo');
const b = new Baz();
b.callFoo();
expect(A.foo).toHaveBeenCalled(); // this will pass
});
Основной вопрос здесь : почему насмешка работает с подходом CommonJS, но неES6, предполагая, что мы используем Babel для компиляции?
Насколько я понимаю, живое связывание ES6, в то время как CommonJS копирует, поэтому я был удивлен, что первое не удалось, и еще более удивило, что второе удалось.Мое лучшее предположение состоит в том, что * import приводит к локальному объекту пространства имен, который отличается в файлах, в которых это делается (то есть A
в es6Baz.js
не совпадает с A
в testEst6A.js
), но на самом деле этодело?И почему require
работает, если это не так?