Sinon: 默认情况下存根 setImmediate 会导致不良行为

创建于 2016-01-07  ·  4评论  ·  资料来源: sinonjs/sinon

我在试图弄清楚为什么存根系统时间导致 csv 写入失败时注意到了这一点。 事实证明,该库有一个阻塞的setImmediate调用: https ://github.com/C2FO/fast-csv/blob/master/lib/extended.js#L18

似乎有一堆库依赖setImmediate来处理无害的事情,而伪造setImmediate会导致所有库出现意外行为:

  • 请求: https ://github.com/sinonjs/sinon/issues/484
  • 异步: https ://github.com/caolan/async/issues/609
  • express.js: https ://github.com/strongloop/express/issues/2447
  • 蓝鸟: http ://stackoverflow.com/q/31403818/329700
  • 合作: https ://github.com/sinonjs/sinon/issues/527

也许期望存根系统时间不会导致 csv 写入失败是不合理的? 在这种情况下,追踪起来特别困难,因为在 Javascript 中,您不能只点击ctrl+c并获得一个堆栈跟踪来告诉您出了什么问题。 仅仅确定了代码的哪一部分被冻结,然后才明白为什么是 sinon 的原因,花了大约 90 分钟。

我不确定修复应该是什么,但它似乎影响了很多库,并且其中至少有一个通过创建自己的setImmediate版本做出了回应,该版本无法被破坏。

如果答案是我应该调用useFakeTimers(0, "Date") ,也许这应该是默认值? 也许这更符合我/人们对世界行为方式的期望?

最有用的评论

为了将来参考,这种形式的函数现在允许您指定伪造的函数:

var clock = sinon.useFakeTimers([now, ]prop1, prop2, ...);

Sets the clock start timestamp and names functions to fake.

Possible functions are setTimeout, clearTimeout, setInterval, clearInterval, setImmediate, clearImmediate and Date. Can also be called without the timestamp.

所以这解决了我在使用 express 时的问题:

clock = sinon.useFakeTimers(1495020000, 'Date');

所有4条评论

我不确定修复应该是什么,但它似乎影响了很多库,并且至少其中一个通过创建自己的 setImmediate 版本做出了回应,该版本无法被破坏。

这是当您使用 setTimeout 时推荐的解决方案,setImmediate 以获得新的调用堆栈的效果(而不是用于控制时间)。

https://github.com/taylorhakes/promise-polyfill/pull/15

是的,我只花了 90 分钟在商业代码库中诊断和修复这个问题。

至少,文档应该提到 setImmediate 将被伪造。

为了将来参考,这种形式的函数现在允许您指定伪造的函数:

var clock = sinon.useFakeTimers([now, ]prop1, prop2, ...);

Sets the clock start timestamp and names functions to fake.

Possible functions are setTimeout, clearTimeout, setInterval, clearInterval, setImmediate, clearImmediate and Date. Can also be called without the timestamp.

所以这解决了我在使用 express 时的问题:

clock = sinon.useFakeTimers(1495020000, 'Date');

该文档现在确实解释了这一点: http ://sinonjs.org/releases/v2.3.2/fake-timers/#var -clock--sinonusefaketimersnow-prop1-prop2-

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