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
  • co: https ://github.com/sinonjs/sinon/issues/527

システム時刻をスタブしてもcsv書き込みが失敗しないと期待するのは不合理かもしれません。 この場合、追跡するのは特に困難です。Javascriptでは、 ctrl+cを押すだけでは、何が悪かったのかを示すスタックトレースを取得できないためです。 コードのどの部分がフリーズしているのかを特定し、sinonが原因である理由を理解するのに約90分かかりました。

修正がどうあるべきかはわかりませんが、多くのライブラリに影響を与えているようで、そのうちの少なくとも1つは、マングルできない独自のバージョンの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.

したがって、これにより、エクスプレスを使用する際の問題が解決しました。

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

全てのコメント4件

修正がどうあるべきかはわかりませんが、多くのライブラリに影響を与えているようで、そのうちの少なくとも1つは、マングルできない独自のバージョンの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.

したがって、これにより、エクスプレスを使用する際の問題が解決しました。

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

ドキュメントはこれを今説明しています: http ://sinonjs.org/releases/v2.3.2/fake-timers/#var -clock--sinonusefaketimersnow-prop1-prop2-

このページは役に立ちましたか?
0 / 5 - 0 評価