node.js - 在单元测试中模拟 es6 模块

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

假设我们有一个文件(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一直显示“Error: Cannot find module './x'”;

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

最佳答案

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

您还应该注意,ES 模块仅在 Node.js 中实验性地(并且相对最近)得到支持。如果您使用 Babel 进行转译,那么您实际上并没有使用 ES 模块。当然,您正在使用语法,但 Babel 将它们转换为 CommonJS“等效项”,并包含 require 调用和 module.exports 赋值。

因此,如果您使用 Babel,您可能可以proxyquire 在测试文件中导入正在测试的模块,即使您在这些模块中使用 ES 模块语法。不过,如果你放弃 Babel,这种情况就会被打破。 :\

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

关于node.js - 在单元测试中模拟 es6 模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50529224/

相关文章:

c# - 我怎样才能将这个工厂类型的方法和数据库调用重构为可测试的?

node.js - 无法使用 npm 和 shell 下载 Node 包

node.js - npm 警告 : npm does not support Node. js v12.4.0

node.js - 未找到 Bower 组件

python - 在 Python 中使用 Mock()

testing - 如何在测试中模拟外部依赖?

javascript - 尝试运行 Node 服务器时出现 "Unexpected Token <"

unit-testing - 一种链接测试的方法,在 Clojure 中一个在另一个之后运行?

c# - Rhino Mocks - 通过多次调用模拟其返回值发生变化(即使传递相同参数)的方法

python - 从 __getattr__ 方法检索的模拟函数