【问题标题】:mocking es6 modules in unit test在单元测试中模拟 es6 模块
【发布时间】:2018-05-25 12:27:02
【问题描述】:

假设我们有一个文件(source.js)要测试:

// source.js
import x from './x';

export default () => x();

而且单元测试代码很简单:

// test.js
import test from 'ava';
import source from './source'

test("OK", t => {
  source();
  t.pass();
});

但这是棘手的事情。测试环境中不存在文件“./x”。由于它是一个单元测试,我们不需要“./x”。我们可以无论如何模拟函数“x()”(使用 sinon 或其他东西)。但是单元测试工具ava一直显示“错误:找不到模块'./x'”;

有没有办法在没有文件“./x”的情况下运行单元测试?

【问题讨论】:

    标签: node.js unit-testing mocking es6-modules ava


    【解决方案1】:

    为此,您需要覆盖导入过程本身。有一些库可以做类似的事情——例如,用proxyquire 覆盖require 函数——但是这些库迫使你调用他们的自定义函数来导入被测模块。换句话说,你需要放弃使用 ES6 模块语法来使用它们。

    您还应该注意,ES 模块仅在 Node.如果您使用 Babel 进行编译,那么您实际上并没有使用 ES 模块。当然,您使用的是语法,但 Babel 将它们转换为 CommonJS “等效”,并带有 require 调用和 module.exports 分配。

    因此,如果您使用 Babel,您可能可以proxyquire 在您的测试文件中导入待测模块,即使您在这些模块中使用 ES 模块语法。但是,如果你离开 Babel,这将中断。 :\

    我个人的建议是避免直接导出您可能需要存根的任何内容。所以像x 这样的函数应该在像import foo from './foo' 这样导入的静态模块中,像foo.x() 这样调用。然后,您可以轻松地使用sinon.stub(foo, 'x') 存根它。当然,'./foo' 文件仍然必须存在,但它真正归结为你想成为 TDD 实践的核心,而不是你愿意在模拟/存根过程中引入多少复杂性。我更喜欢放松前者以避免后者,但最终取决于你。

    【讨论】:

    • 感谢您的回答。
    • 感谢您的回答。我正在使用具有“--experimental-modules”功能的最新 node.js。我可以接受实验性的,因为我可以通过摆脱 bable 来逃避很多额外的工作。所以,我所有的源代码文件都是 *.mjs。但是,AVA 对 mjs 的支持并不好。而且它使用的bable插件无法生成正确的代码。这会导致测试过程中出现一些语法错误,而在产品环境中运行相同的代码。
    • 让我稍微改变一下我的问题。我们有 x.mjs 和 source.mjs。并且 x.mjs 确实存在,但是将它交给 bable 会有一些错误(我不知道为什么也不想调查)。是否可以在不更改上面代码的情况下让 test.js(或 test.mjs)运行?
    • 我几乎可以保证它不能与 Babel 一起工作的原因是 .mjs 扩展。至于你的新问题,我对 AVA 一无所知,但只要存在“x.mjs”或“x.js”,你的导入语法就可以了。但是,您的测试是否通过当然取决于该文件是否导出函数
    【解决方案2】:

    如果您使用的是 Jest,可以通过使用 jest 的内置 mock 方法模拟导入来轻松实现。 请参阅下面的链接以了解有关 ES6 导入模拟的更多信息

    https://jestjs.io/docs/en/es6-class-mocks

    【讨论】:

    • 这是关于 ES6 的类,而不是模块。独立于测试运行器的通用解决方案也很好。
    • 值得注意的是,jest 目前不支持原生 ES6 模块。如果您使用 Jest 进行测试,那么您几乎肯定会使用 babel 转译模块。
    【解决方案3】:

    如果你在 JavaScript 中使用 jest,这很简单:

    使用jest.mock('MODULE_NAME')

    如果是node模块或者自己的模块,没问题jest会自动mock那个模块。

    【讨论】:

      猜你喜欢
      • 2023-03-13
      • 2015-02-04
      • 2017-09-25
      • 1970-01-01
      • 2013-03-25
      • 2015-12-10
      • 2016-08-24
      • 2013-07-07
      • 2018-12-21
      相关资源
      最近更新 更多