假设我们有一个文件(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/