在支持它们的环境中运行的EcmaScript模块(意味着它们尚未使用Babel编译到ES5)并导出了某种default
函数,因此无法进行存根,因为ES命名空间根据规范是不可变的。 Sinon对此无能为力,因此当您尝试执行此操作时,我们会明确抛出一个错误: 'ES Modules cannot be stubbed'
。
但是@jdalton已经制作了esm
,它是Node的运行时加载器,能够加载EcmaScript模块( *.mjs
),并允许使用Sinon等进行存根,他添加了mutableNamespace
选项到esm
。
在“如何”部分下应该有一篇文章,展示如何使用esm
和该选项以及一个测试脚本来设置npm
来执行节点。
参考:
我一直在考虑写这个:)
“问题”是,可以使用多种不同的方式使用esm
,但是我们至少应该涵盖最常见的情况,我认为这是通过require
标志来实现的。 node
过程。 我开始在这里充实如何使用配置文件,但似乎也可以提供json字符串作为环境变量(如果使用代码,则除了选项哈希之外)。
嗨@ fatso83!
cjs.mutableNamespace
选项默认情况下处于启用状态,因此无需进行任何配置。 存根可以与.js
但不能与.mjs
_( .mjs
文件被锁定,因此没有esm
选项)_一起使用。
@jdalton感谢您让我们知道js
与mjs
区别。 这就解释了为什么这个人无法正常工作。
抄送@ 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支持。 有可能的。 我在这篇博客文章中介绍了实现:
如果有人愿意接受,将很乐意在这里提供帮助。
@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的好东西。
最有用的评论
@giltayar祝贺您实现了ESM支持! 顺便说一句,很棒的文章。 我们一直说过,在符合ESM运行时时ES模块存根是不可能的,但是我们也说过(如上),应该在链接级别使用proxyquire,rewire或... Quibble之类的东西来处理它。您在哪里添加了支持:)
在我的工作项目中,我们使用了
proxyquire
来消除ES模块的依赖关系:这在Quibble(由TestDouble使用)中相当,本文中有一个这样的示例,但是Quibble不支持部分存根,因此它们的功能有些不同。
因此,按照先前的说法,Sinon绝不会明确添加对模拟ES模块的支持,因为最好将其留给Quibble,Proxyquire,Rewire, NormalModuleReplacementPlugin (webpack)和所有其他方式来实现,即100%环境依赖。