我正在使用AVA + sinon来构建我的单元测试。因为我需要ES6模块而且我不喜欢babel,所以我在我的项目中使用mjs文件,包括测试文件。我使用“--experimental-modules”参数来启动我的项目,并在测试中使用“esm”包。以下是我的ava配置和测试代码。
"ava": {
"require": [
"esm"
],
"babel": false,
"extensions": [
"mjs"
]
},
// test.mjs
import test from 'ava';
import sinon from 'sinon';
import { receiver } from '../src/receiver';
import * as factory from '../src/factory';
test('pipeline get called', async t => {
const stub_factory = sinon.stub(factory, 'backbone_factory');
t.pass();
});
但我收到错误消息:
TypeError {
message: 'ES Modules cannot be stubbed',
}
如何在没有babel的情况下存根ES6模块?
答案 0 :(得分:1)
According to John-David Dalton,@esm
包的创建者,只能改变*.js
个文件的名称空间 - *.mjs
文件被锁定。
这意味着Sinon(以及所有其他软件)无法存根这些模块 - 正如错误消息所指出的那样。您可以尝试使用link seam,使用proxyquire
或rewire
,这意味着上面的测试将是这样的:
// assuming that `receiver` uses `factory` internally
// comment out the import - we'll use proxyquire
// import * as factory from '../src/factory';
// import { receiver } from '../src/receiver';
const factory = { backbone_factory: sinon.stub() };
const receiver = proxyquire('../src/receiver', { './factory' : factory });
但是,由于上述原因,我并非100%确定这是有效的,但值得尝试。
旧答案 - 仅对*.js
个文件有效(不是*.mjs
)。
您需要将选项传递给esm
,这将允许您拥有可变的命名空间。默认情况下,ES模块不可变,这意味着Sinon不能执行zilch。
cjs.mutableNamespace
中描述了名为esm
的选项,它将修改Node的运行时以允许您更改导出。
如何启用该选项取决于您加载// Set options as a parameter, environment variable, or rc file.
的方式,但自述文件显示:.esmrc.json
由于您没有自己加载模块,我假设环境变量或rc文件是您唯一的两个选项。在env变量中填充json可能会很混乱,所以我建议在名为{
"cjs": {
"mutableNamespace": "true"
}
}
的文件中填充以下内容:
esm
我自己从来没有将选项传递给mutableNamespace
,所以不知道它是否在没有修改的情况下运行,并且上面的代码本身不能运行,这意味着我无法在你的案例中测试它,但我认为它应该是非常正确的。
编辑:x=my_func(arg)
if x:
do something
return x
选项是默认选项,因此无需指定它。