在我遇到问题之前,我将从设置开始。让我们从我们想要监视其命名导出的基本文件开始:
// 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
});
这里的主要问题是:假设我们使用Babel进行编译,为什么模拟使用CommonJS方法而不是ES6方法?
我的理解是,ES6活着绑定,而CommonJS副本,所以我很惊讶前者失败了,后者更加惊讶成功了。我最好的猜测是,* import导致本地命名空间对象在文件中的不同(即A
中的es6Baz.js
与{{1}中的A
不同}},但实际情况是这样吗?为什么testEst6A.js
会起作用呢?