Sinon: `getStackFrames()[0]`の問題

作成日 2016年06月12日  ·  3コメント  ·  ソース: sinonjs/sinon

問題が発生し、お急ぎの場合は承知しておりますが、問題を迅速に理解、解決、解決できるように、情報を提供してください。

  • シノンバージョン:1.17.4
  • 環境:Firefox
  • URLの例:
  • 使用している他のライブラリ:mocha、chai

何が起こると思いましたか?

内部のSinonエラーではなく、自分のエラーが報告されることを期待していました。

実際に何が起こるか

内部Sinonエラーが表示されます。

再現する方法

誤った動作を再現する方法を_コードで_説明します。
またはJSBinまたは同様のコードへのリンク

例についてはこれを参照してください

sinon/lib/sinon/call.jsでは、このコードはthis.getStackFrames(...)[0] is undefinedというエラーを私に与えています:

      if (this.stack) {
            callStr += this.getStackFrames()[0].replace(/^\s*(?:at\s+|@)?/, " at ");
      }

以下から:

    getStackFrames: function () {
        // Omit the error message and the two top stack frames in sinon itself:
        return this.stack && this.stack.split("\n").slice(3);
    },

... sliceが空の配列を返しているようです。

特定のコードサンプルなしで続行するには、これで十分かもしれないと思います。 ありがとう!

最も参考になるコメント

これはおそらく、Nodeでも機能する少し優れたバージョンです。

let sinon = require('sinon');

function test() {

  let stub1 = sinon.stub().returns( Promise.resolve({}) );
  let stub2 = sinon.stub();

  function run() {
    return stub1().then( stub2 );
  }

  run()
  .then( () => sinon.assert.calledTwice( stub2 ) )
  .catch( console.log );

}

setTimeout( test, 0 );

全てのコメント3件

これでは不十分です。 SinonのAPIを使用したコードはまったく表示されません。 シノンの内部について言及しただけですが、外部についてはどうでしょうか。 何を達成しようとしていますか? 何を達成しようとしているのか、どのように、何が機能していないのかを明確にする情報を追加すると、これを再度開くことができます。

これは、Sinon1.17.6を搭載したMac用Chrome55.0.2883.95(最新版はhttp://sinonjs.org/で入手可能)で再現できます。

ここでJSBinが減少したテストケースである: http://jsbin.com/mufotihiwo/edit?js 、コンソール、出力

基本的に、スタブがポイントフリーでPromise#then()に渡される場合、Sinonは3行より長いスタックトレースを持つ必要があると考えていますが、そうではありません。

何が原因なのかを正確に把握する機会はまだありません。

これは、コールバックがVMによって直接呼び出されるためだと思います。つまり、スタックには何もありません。 したがって、Sinonが最初の3行( spy.invoke()から開始)を切り落とすと、何も残りません。 次に、 String#replace() getStackFrames()[0]undefinedため、 call.toStringString#replace()は失敗します。

緩和戦略は、次のような防御チェックをtoString()入れることだと思います。

callStr += ( this.getStackFrames()[0] || 'unknown function' ).replace(/^\s*(?:at\s+|@)?/, " at ");

これはおそらく、Nodeでも機能する少し優れたバージョンです。

let sinon = require('sinon');

function test() {

  let stub1 = sinon.stub().returns( Promise.resolve({}) );
  let stub2 = sinon.stub();

  function run() {
    return stub1().then( stub2 );
  }

  run()
  .then( () => sinon.assert.calledTwice( stub2 ) )
  .catch( console.log );

}

setTimeout( test, 0 );
このページは役に立ちましたか?
0 / 5 - 0 評価