Sinon: Encadear sinon.stub() com vários .withArgs apenas stubs a última declaração

Criado em 25 set. 2012  ·  23Comentários  ·  Fonte: sinonjs/sinon

Encadear sinon.stub() com vários .withArgs apenas stubs a última declaração

var stubbedFunction = sinon.stub().withArgs(argumento1).returns(valor1).withArgs(argumento2).returns(valor2);

então apenas a última declaração (.withArgs(argument2).returns(value2)) é realmente stub

Comentários muito úteis

Isso está funcionando corretamente com o Sinon 1.7.3:

var s = sinon.stub();
s.withArgs(1).returns('a');
s.withArgs(2).returns('b');
s(1); // -> 'a'
s(2); // -> 'b'
s(3) // -> undefined

Todos 23 comentários

Precisa fazer withArgs modificar e retornar o stub original a partir do qual foi criado, quando disponível.

+1 Para isso. Em uma nota relacionada, gostaria que withArgs permitisse opcionalmente a passagem para o método original para argumentos não correspondidos.

Por exemplo, se eu quiser stub o método fs.readFileSync() do Node.js, quero que o Sinon mantenha a implementação original para que require() (que usa readFileSync ) não seja quebrado, mas use o método stubbed para um arquivo específico para meus testes.

Exemplo do comentário anterior:

beforeEach(function() {
  global.fs = require('fs');
  sinon.stub(fs, 'readFileSync').onlyWithArgs('my-file.txt').returns('Contents of file');

  // Then require the module under test, which uses fs.readFileSync() internally
  // require() uses original method with correct calling context
  global.myModule = require('../src/my-module');
});

afterEach(function() {
  fs.readFileSync.restore();
});

it('does something with the file', function() {
  expect(myModule.loadFromFile()).toEqual('Contents of file');
});

Gostaria de sugerir que @froots post acima seja postado em algum lugar nos documentos. Pesquisei muito antes de encontrar esta solução sobre como simular arquivos que incluem outras dependências por meio de require

Boa ideia. Quer dar uma espiadinha nisso? http://github.com/cjohansen/sinon-web/

Isso está funcionando corretamente com o Sinon 1.7.3:

var s = sinon.stub();
s.withArgs(1).returns('a');
s.withArgs(2).returns('b');
s(1); // -> 'a'
s(2); // -> 'b'
s(3) // -> undefined

Eu não acho que seja um exemplo disso funcionando, já que ainda não encadeia (você tem que usar o stub/mock original).

Verdadeiro. Mas é bom o suficiente e deixa claro o que está acontecendo. O encadeamento deixa espaço para interpretação.

Concordo com @mantoni. A finalidade do stub é indicar a resposta contratual do serviço/consulta. Este estilo expressa isso melhor.

Eu acho que os documentos provavelmente poderiam ser melhorados aqui.

Eu esperava que o seguinte funcionasse:

var someObj = {
    someProp: sinon.stub().withArgs("foo").returns(true)
}

Obviamente não funcionou como pretendido. Mas, mais importante, não falhou corretamente. Em vez de someObj.someProp não retornar true quando foo não for fornecido, ele sempre retornou true . Como a cláusula returns retorna uma instância Behavior, someObj.someProp retorna true independentemente da entrada.

Eu entendo a lógica por trás da estrutura de encadeamento retornando diferentes tipos de objetos. Mas os usuários são enganados quanto ao que são esses objetos retornados. Como os métodos que CallObjects e Behaviors expõem correspondem à API fornecida por Stubs, é fácil ver por que alguém poderia supor que eles _foram_ stubs.

Concordo com @jasonkarns. Acabei de cair na mesma "armadilha": inserir a declaração de stub não retorna a instância de stub esperada. No entanto, o encadeamento parece funcionar conforme o esperado ao usar simulações:

var someObj = {
    someProp: sinon.mock().withArgs("foo").returns(true)
}

Existe alguma razão para isso?

Não tenho certeza se estou perdendo alguma coisa, mas o ponto @froots é possível agora? Tinha que fazer isso:

sinon.stub(fs, 'readdirSync', (dir) => {
    if (dir === 'foo-path') {
        return [
            'my.js',
            'fake.js',
            'stuff.js'
        ];
    }

    return fsReaddir(dir);
});

Queria fazer algo como:

var myStub = sinon.stub(fs, 'readdirSync', fs.readdirSync);

myStub
    .withArgs('foo-path')
    .returns([
        'my.js',
        'fake.js',
        'stuff.js'
    ]);

Eu acho que isso está corrigido agora, o exemplo abaixo funciona como pretendido com [email protected]

var Dummy = {
    doSomething: function(something) {
        return 'doing ...' + something;
    }
}

sinon.stub(Dummy, 'doSomething')
    .withArgs('sleep').returns('sleepy')
    .withArgs('eat').returns('eating');

console.log(Dummy.doSomething('sleep'));
console.log(Dummy.doSomething('eat'));

@valentin-radulescu-hs ainda falha do meu lado com 1.17.7 .
Ainda leva o último returns como o único valor de retorno, independentemente do withArgs (conforme apontado por @jasonkarns https://github.com/sinonjs/sinon/issues/176#issuecomment- 78191790).

O que funciona para mim é a resposta do @mantoni https://github.com/sinonjs/sinon/issues/176#issuecomment -33636496, não encadeando withArgs() .

var s = sinon.stub();
s.withArgs(1).returns('a');
s.withArgs(2).returns('b');

@zurfyx você está executando no nó ou no navegador? Qual versão do nó/navegador você está usando? Não tenho certeza se isso importa, mas eu gostaria de tentar replicar do meu lado.

Olá @valentin-radulescu-hs. Estou executando no Node, usando babel-cli 6.22.2

  • Nó 6.9.4
  • NPM 3.10.10

Desculpe pelo atraso na resposta

@zurfyx Eu tentei replicar com a configuração que você mencionou usando o mesmo código que escrevi acima e ele gera no console sleepy e eating conforme o esperado. Não tenho certeza por que está causando problemas 😢

@zurfyx Só para ter _totalmente_ certeza, você já tentou isso?

grep version node_modules/sinon/package.json
rm -r node_modules
rm npm-shrinkwrap
npm install
grep version node_modules/sinon/package.json

Na maioria das vezes estou tendo problemas é devido a versão do pacote que estou esperando não ser a mesma que está instalada.

@fatso83 Também não funciona. A versão de saída grep ainda é 1.1.7.7 .

Este é o meu teste completo, caso possa ajudar:

  it('test', () => {
    const s = sinon.stub();
    s.withArgs('a').returns('1');
    s.withArgs('b').returns('2');

    console.info(s('c'));
  });

s('a') : '1'
s('b') : '2'
s('c') : undefined

  it('test', () => {
    const s = sinon.stub()
      .withArgs('a').returns('1')
      .withArgs('b').returns('2');

    console.info(s('c'));
  });

s('a') : '2'
s('b') : '2'
s('c') : '2'

Eu sou capaz de reproduzir esse comportamento usando sinon.createStubInstance também.

const stub = sandbox.stub();
      const myObj = function(){};
      const objOne = sinon.createStubInstance(myObj);
      const objTwo = sinon.createStubInstance(myObj);
      stub.withArgs(objOne).returns('1');
      stub.withArgs(objTwo).returns('2');

      console.info(stub(objOne));
      console.info(stub(objTwo));

Saída:
2 2

Eu pensei que sinon.createStubInstance deveria criar um novo objeto stub. Isso é incorreto?

Não tenho certeza se esta pergunta pertence a este tópico, mas definitivamente tem algo a ver com isso. Em um projeto com sinon 1.17.7 eu costumava encadear várias instruções withArgs , onde a última era um matcher "grab-all" que agia como padrão. Por exemplo:

const s = sinon.stub();
s.withArgs(1).returns(1)
 .withArgs(2).returns(2)
 .withArgs(sinon.match.any).returns('my-default-value')

s(1) // 1
s(5) // my-default-value

Agora estou usando 4.1.3 e o comportamento mudou, sempre retorna my-default-value . Isso foi pretendido? Em caso afirmativo, existe uma maneira de definir um valor padrão/fallback em uma cadeia de withArgs ?

Eu não acho que uma mudança foi planejada. Se você puder fornecer uma correção para o
regressão fique à vontade! Eu posso ajudar a rastrear onde aconteceu usando got
culpa.

De homem. 15. jan. 2018, 11.13 skrev David García [email protected] :

Não tenho certeza se esta pergunta pertence a este tópico, mas
definitivamente tem algo a ver com isso. Em um projeto com o sino 1.17.7 I
usado para encadear várias instruções withArgs, onde a última era uma
matcher "grab-all" que agia como padrão. Por exemplo:

const s = sinon.stub();s.withArgs(1).returns(1)
.withArgs(2).returns(2)
.withArgs(sinon.match.any).returns('my-default-value')
s(1) // 1s(5) // meu valor padrão

Agora estou usando 4.1.3 e o comportamento mudou, sempre retorna
meu-valor-padrão. Isso foi pretendido? Em caso afirmativo, existe uma maneira de definir um
valor padrão/fallback em uma cadeia de withArgs?


Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/sinonjs/sinon/issues/176#issuecomment-357638653 ou silenciar
o segmento
https://github.com/notifications/unsubscribe-auth/AAluXMzqALJ0JlAM3hUaiK1SSyca9H74ks5tKyS4gaJpZM4AK2eu
.

>

[imagem: --]

Carl-Erik Kopseng
[imagem: https://]about.me/kopseng
https://about.me/kopseng?promo=email_sig&utm_source=email_sig&utm_medium=email_sig&utm_campaign=external_links

@fatso83 Eu reduzi e aparentemente foi de propósito . Para mim, parece mais natural especificar um fallback na última instrução withArgs , embora neste caso apenas mudar a ordem e colocar .withArgs(sinon.match.any) na primeira posição resolva o problema

Esta página foi útil?
0 / 5 - 0 avaliações