假设我们有一个要测试的文件(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"?
答案 0 :(得分:1)
如果您使用的是Jest,则可以使用 jest 的内置 mock 方法对导入进行模拟来轻松实现。 请参考下面的链接以找到有关ES6导入模拟的更多信息
答案 1 :(得分:0)
为此,您需要覆盖导入过程本身。有一些库可以做类似的事情 - 例如用proxyquire覆盖require
函数 - 但是这些会强制你调用它们的自定义函数来导入被测模块。换句话说,您需要放弃使用ES6模块语法来使用它们。
您还应该注意,ES模块仅在Node中通过实验(以及相对最近)支持。如果您正在使用Babel进行转换,那么您实际上 使用ES模块。当然,您正在使用语法,但Babel将它们转换为CommonJS"等同物",完成require
次呼叫和module.exports
分配。
因此,如果您正在使用Babel,即使您在这些模块中使用ES模块语法,也可以proxyquire
在测试文件中导入待测模块。但是,如果你从巴贝尔转移,这将打破。 :\
我个人的建议是避免直接导出您可能需要的任何存根。因此,像x
这样的函数应该在像import foo from './foo'
这样导入的静态模块中,并像foo.x()
一样调用。然后,您可以使用sinon.stub(foo, 'x')
轻松将其存根。当然,'./foo'
文件仍然必须存在,但它真正归结为你想要关于TDD实践的核心程度与你愿意为你的模拟引入多少复杂性/存根过程。我更喜欢放松前者以避免后者,但最终它取决于你。
答案 2 :(得分:0)
如果您在JavaScript中使用笑话,这非常简单:
使用jest.mock('MODULE_NAME')
如果它是节点模块或您自己的模块,则没有问题的玩笑会自动模拟该模块。