在单元测试

时间:2018-05-25 12:27:03

标签: 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一直显示"错误:无法找到模块' ./ x'";

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

3 个答案:

答案 0 :(得分:1)

如果您使用的是Jest,则可以使用 jest 的内置 mock 方法对导入进行模拟来轻松实现。 请参考下面的链接以找到有关ES6导入模拟的更多信息

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

答案 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')

如果它是节点模块或您自己的模块,则没有问题的玩笑会自动模拟该模块。