从没有babel的ES6模块中获取功能

时间:2018-06-08 14:54:49

标签: sinon es6-modules ava

我正在使用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模块?

1 个答案:

答案 0 :(得分:1)

According to John-David Dalton@esm包的创建者,只能改变*.js个文件的名称空间 - *.mjs文件被锁定

这意味着Sinon(以及所有其他软件)无法存根这些模块 - 正如错误消息所指出的那样。您可以尝试使用link seam,使用proxyquirerewire,这意味着上面的测试将是这样的:

// 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 选项是默认选项,因此无需指定它。