Sinon: Problema com `getStackFrames () [0]`

Criado em 12 jun. 2016  ·  3Comentários  ·  Fonte: sinonjs/sinon

Entendemos que você tem um problema e está com pressa, mas forneça algumas informações para que seja mais provável que seu problema seja compreendido, trabalhado e resolvido rapidamente.

  • Versão Sinon: 1.17.4
  • Ambiente: Firefox
  • URL de exemplo:
  • Outras bibliotecas que você está usando: mocha, chai

O que você esperava que acontecesse?

Eu esperava que meu próprio erro fosse relatado, não um erro interno do Sinon.

O que realmente acontece

Um erro interno do Sinon é mostrado.

Como reproduzir

Descreva _com código_ como reproduzir o comportamento defeituoso,
ou link para código em JSBin ou similar

Veja isso como um exemplo

Em sinon/lib/sinon/call.js , este código está me dando o erro de que this.getStackFrames(...)[0] is undefined :

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

Do seguinte:

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

... parece que slice está retornando um array vazio.

Espero que isso seja o suficiente para você continuar sem um exemplo de código específico. Obrigado!

Comentários muito úteis

Esta é talvez uma versão um pouco melhor que também funciona no 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 );

Todos 3 comentários

Isso não é suficiente. Não vejo nenhum código usando a API do Sinon. Você acabou de mencionar os internos do Sinon, mas e os externos? O que você está tentando alcançar? Você pode reabrir isso se adicionar mais informações que deixem claro o que você está tentando alcançar, como e o que não está funcionando.

Consigo reproduzir isso no Chrome 55.0.2883.95 para Mac com Sinon 1.17.6 (o último disponível em http://sinonjs.org/).

Aqui está um JSBin com um caso de teste reduzido: http://jsbin.com/mufotihiwo/edit?js , console, saída

Essencialmente, parece que quando um stub é passado sem pontos para Promise#then() , Sinon _ pensa_ que deveria ter um rastreamento de pilha com mais de 3 linhas, mas não tem.

Ainda não tive a chance de descobrir exatamente o que causa isso.

Acredito que isso seja porque o retorno de chamada é invocado diretamente pela VM, o que significa que não há nada na pilha. Então, quando o Sinon corta as primeiras 3 linhas (começando em spy.invoke() ), não há mais nada. Então o String#replace() em call.toString falha porque getStackFrames()[0] é undefined .

_Acho_ que uma estratégia de mitigação seria simplesmente colocar um cheque defensivo em toString() que se parecesse com:

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

Esta é talvez uma versão um pouco melhor que também funciona no 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 );
Esta página foi útil?
0 / 5 - 0 avaliações