Sinon: 记录如何配置Node以允许存根EcmaScript模块

创建于 2018-06-08  ·  17评论  ·  资料来源: sinonjs/sinon

在支持它们的环境中运行的EcmaScript模块(意味着它们尚未使用Babel编译到ES5)并导出了某种default函数,因此无法进行存根,因为ES命名空间根据规范是不可变的。 Sinon对此无能为力,因此当您尝试执行此操作时,我们会明确抛出一个错误: 'ES Modules cannot be stubbed'

但是@jdalton已经制作了esm ,它是Node的运行时加载器,能够加载EcmaScript模块( *.mjs ),并允许使用Sinon等进行存根,他添加mutableNamespace选项esm

在“如何”部分下应该有一篇文章,展示如何使用esm和该选项以及一个测试脚本来设置npm来执行节点。

参考:

Documentation ES2015+ Help wanted good first issue hacktoberfest pinned

最有用的评论

@giltayar祝贺您实现了ESM支持! 顺便说一句,很棒的文章。 我们一直说过,在符合ESM运行时时ES模块存根是不可能的,但是我们也说过(如上),应该在链接级别使用proxyquire,rewire或... Quibble之类的东西来处理它。您在哪里添加了支持:)

在我的工作项目中,我们使用了proxyquire来消除ES模块的依赖关系:

proxyquire('./mylib.mjs', {doSomething: () => 'done'})

这在Quibble(由TestDouble使用)中相当,本文中有一个这样的示例,但是Quibble不支持部分存根,因此它们的功能有些不同。

await quibble.esm('./mylib.mjs', {doSomething: () => 'done'}, 'yabadabadoing') // not sure what this third param does ...

因此,按照先前的说法,Sinon绝不会明确添加对模拟ES模块的支持,因为最好将其留给Quibble,Proxyquire,Rewire, NormalModuleReplacementPlugin (webpack)和所有其他方式来实现,即100%环境依赖。

所有17条评论

我一直在考虑写这个:)

“问题”是,可以使用多种不同的方式使用esm ,但是我们至少应该涵盖最常见的情况,我认为这是通过require标志来实现的。 node过程。 我开始在这里充实如何使用配置文件,但似乎也可以提供json字符串作为环境变量(如果使用代码,则除了选项哈希之外)。

嗨@ fatso83!

cjs.mutableNamespace选项默认情况下处于启用状态,因此无需进行任何配置。 存根可以与.js但不能与.mjs _( .mjs文件被锁定,因此没有esm选项)_一起使用。

@jdalton感谢您让我们知道jsmjs区别。 这就解释了为什么这个人无法正常工作。

抄送@ jim-king-2000

我想以最小的成本编写单元测试。 如果解决方案如此棘手,我宁愿使用模拟放弃单元测试。 毕竟,模拟测试并不是构建健壮的在线系统的必要方法。 但是,作为最后的选择,sinon是否可以为我包装“ proxyrequire”(或类似的东西)?

@ jim-king-2000超出范围。 您已明确选择使用应该导出为不变的模块系统。 不幸的是,这是您必须自己承担的费用。 包装模块加载程序,使其在各种场景(节点,浏览器,带有/不带有编译器等)中工作都非常昂贵,并且实际上与该项目的既定目标没有任何关系。

我不太了解sinon和模块系统的相关性(很抱歉)。 我需要的是一个没有babel的js / node模拟单元测试框架(或库,例如java对应物,mockito)。 那么,它存在吗?

简而言之,对于您的特定细分市场:当前不是:sob:
总的来说:是的,对于框架和运行时的几乎任何组合,都有一些方法可以实现这一目标。

用Java术语来说,这就像使用Java static方法实现整个系统,然后尝试使用Mockito模拟类。 不能做

话虽如此,所有要做的就是将*.mjs文件重命名为*.js 。 这似乎是一种实用的中间方法,因为您将获得可测试性而没有任何已知的缺点。

对于Java的静态函数模拟,我们使用powermock。 但是我可能不完全了解这种比较。 顺便说一句,我不喜欢Java,它的发展太慢了。 现在,它仍然支持异步/ AWAIT。

我到处都使用* .mjs,所有源代码都是mjs文件。 此外,这意味着我不得不再次求助于babel(引入额外的开发/运行时工作和混乱的调用堆栈)。 如果我只能将测试文件更改回* .js,那就可以了。

在我找到其他低成本方法之前,我将放弃模拟(其他测试完好无损)。

@ fatso83感谢您

有没有人尝试古怪? 🤔

仅供参考,我在“ testdouble.js”(一个模拟库)中实现了Node.js ESM支持。 有可能的。 我在这篇博客文章中介绍了实现:

https://dev.to/giltayar/mock-all-you-want-supporting-es-modules-in-the-testdouble-js-mocking-library-3gh1

如果有人愿意接受,将很乐意在这里提供帮助。

@giltayar祝贺您实现了ESM支持! 顺便说一句,很棒的文章。 我们一直说过,在符合ESM运行时时ES模块存根是不可能的,但是我们也说过(如上),应该在链接级别使用proxyquire,rewire或... Quibble之类的东西来处理它。您在哪里添加了支持:)

在我的工作项目中,我们使用了proxyquire来消除ES模块的依赖关系:

proxyquire('./mylib.mjs', {doSomething: () => 'done'})

这在Quibble(由TestDouble使用)中相当,本文中有一个这样的示例,但是Quibble不支持部分存根,因此它们的功能有些不同。

await quibble.esm('./mylib.mjs', {doSomething: () => 'done'}, 'yabadabadoing') // not sure what this third param does ...

因此,按照先前的说法,Sinon绝不会明确添加对模拟ES模块的支持,因为最好将其留给Quibble,Proxyquire,Rewire, NormalModuleReplacementPlugin (webpack)和所有其他方式来实现,即100%环境依赖。

@ fatso83如果我可能会问为什么这是一个如此

Jest没有记录任何解决方案,这里没有解决方案。 我几乎放弃了,直到找到@giltayar的文章。 这样的解脱。 在了解到我可以使用testdouble.js之前,我进行了一些古怪的工作。

在JavaScript中,每个软件包都有其自己的文档样式,而且大多数时候没有真正的API文档已经非常困难,而且还必须弄清楚测试库的工作方式,模拟库的工作方式以及用于模拟库的模块加载器的工作量太高了。

我完全同意,如果您说您专注于Sinon,而其他人则可以专注于将这些软件包连接在一起以供“最终用户”程序员使用。 我只想表明,像我这样的程序员确实有痛苦,并且我相信,如果简化流程,尤其是在未来几年中,许多人都将迁移到ES模块,很多人都会感到高兴。

我没有这么深刻的技术了解,我只是认为我的经验反馈可能会有所帮助

@ fatso83如果我可能会问为什么这是一个如此

让我重申一遍:锡诺大学维护者的意见是,处理假冒进口商品超出了锡诺大学的范围,可以通过专门的图书馆更好地解决。

通常,在每个运行时中创建一个试图做所有事情的库是没有意义的。 规模甚至更大,资金充裕的开源项目都没有尝试这样做。

Jest没有记录任何解决方案,这里没有解决方案。 我几乎放弃了,直到找到@giltayar的文章。 这样的解脱。 在了解到我可以使用testdouble.js之前,我进行了一些古怪的工作。

不同的库做出不同的选择。

testdouble.js的维护者可以做出自己的选择。 他们决定发布测验并将其整合到他们的图书馆中。 对他们有好处。 如果您喜欢他们的解决方案,那么请务必使用它。 除了爱和尊重@searls

在JavaScript中,每个软件包都有其自己的文档样式,而且大多数时候没有真正的API文档已经非常困难,而且还必须弄清楚测试库的工作方式,模拟库的工作方式以及用于模拟库的模块加载器的工作量太高了。

我完全同意,如果您说您专注于Sinon,而其他人则可以专注于将这些软件包连接在一起以供“最终用户”程序员使用。 我只想表明,像我这样的程序员确实有痛苦,并且我相信,如果简化流程,尤其是在未来几年中,许多人都将迁移到ES模块,很多人都会感到高兴。

我们并不是在这里解决JavaScript生态系统中的每一个问题。

十多年来,各种维护者免费提供了锡诺族图书馆。 实际上,维护这些库的所有工作都是在维护者的空闲时间以无偿方式完成的。 我们正在专业地使用JavaScript,并与您分享您的挫败感。 但是,我们只有这么多时间免费赠送。

我没有这么深刻的技术了解,我只是认为我的经验反馈可能会有所帮助

如果您写了一篇关于您的挫败感模拟依赖关系的博客文章,直到您找到了一个对您来说效果很好的解决方案,以及如何使用testdouble.js来成功实现特定的JavaScript加载方式,那么这将对您有所帮助。

如果事实证明这是一篇不错的博客文章,我很乐意在sinonjs.org上推广它。

@mroderick我想我应该首先弄清楚您和Sinon的维护者有我最大的敬意!

我们并不是在这里解决JavaScript生态系统中的每一个问题。

绝对不是,那只是为了表明与其他语言相比,对帮助的需求可能更大(这只是我的猜测)。

对于Sinan而言,处理进口假货是不可行的,可以通过专门的图书馆更好地解决。

就像我说的那样,很公平,我可以理解,也许您对实现这些功能所涉及的工作有更深入的了解。 此外,加载程序API仍处于试验阶段。

我目前正在开发一个小型CLI工具,计划在有可用版本时尽快将其作为开源发布。 如果这样做,我考虑写一篇有关它的博客文章。 之前我还是会尝试使用proxyquire尝试Sinon,因为我读了太多有关Sinon的好东西。

之前我还是会尝试使用proxyquire尝试Sinon,因为我读了太多有关Sinon的好东西。

我们提供了有关如何执行此操作的指南: https :

如果您发现该指南有待改进,请发送拉取请求👍

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

stevenmusumeche picture stevenmusumeche  ·  3评论

stephanwlee picture stephanwlee  ·  3评论

optimatex picture optimatex  ·  4评论

OscarF picture OscarF  ·  4评论

brettz9 picture brettz9  ·  3评论