Sinon: Le chaînage sinon.stub() avec plusieurs .withArgs ne remplace que la dernière déclaration

Créé le 25 sept. 2012  ·  23Commentaires  ·  Source: sinonjs/sinon

Le chaînage sinon.stub() avec plusieurs .withArgs ne remplace que la dernière déclaration

var stubbedFunction = sinon.stub().withArgs(argument1).returns(value1).withArgs(argument2).returns(value2);

alors seule la dernière déclaration (.withArgs(argument2).returns(value2)) est réellement stub

Commentaire le plus utile

Cela fonctionne correctement avec 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

Tous les 23 commentaires

Nécessité de modifier withArgs et de renvoyer le stub d'origine à partir duquel il a été créé, lorsqu'il est disponible.

+1 Pour ça. Sur une note connexe, j'aimerais que withArgs autorise éventuellement le passage à la méthode d'origine pour les arguments non correspondants.

Par exemple, si je veux remplacer la méthode Node.js fs.readFileSync() , je veux que Sinon conserve l'implémentation d'origine afin que require() (qui utilise readFileSync ) ne soit pas cassé, mais utilisez la méthode stubbed pour un fichier particulier pour mes tests.

Exemple pour le commentaire précédent :

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');
});

Je voudrais suggérer que @froots au-dessus du message soit publié quelque part dans la documentation. J'ai cherché longtemps avant de trouver cette solution sur la façon de simuler des fichiers qui incluent d'autres dépendances via require

Bonne idée. Voulez-vous essayer? http://github.com/cjohansen/sinon-web/

Cela fonctionne correctement avec 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

Je ne pense pas que ce soit un exemple de fonctionnement, car il ne s'enchaîne toujours pas (vous devez utiliser le stub/mock d'origine).

Vrai. Mais c'est assez bon et cela montre clairement ce qui se passe. L'enchaînement laisse place à l'interprétation.

Je suis d'accord avec @mantoni. Le talon a pour but d'indiquer la réponse contractuelle du service/demande. Ce style exprime mieux cela.

Je pense que la documentation pourrait probablement être améliorée ici.

Je m'attendais à ce que les éléments suivants fonctionnent:

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

Cela n'a évidemment pas fonctionné comme prévu. Mais, plus important encore, il n'a pas échoué correctement. Au lieu someObj.someProp échoue à renvoyer true lorsque foo n'est pas fourni, il a toujours renvoyé true . Étant donné que la clause returns renvoie une instance Behavior, someObj.someProp renvoie consciencieusement true , quelle que soit l'entrée.

Je comprends la logique derrière la structure de chaînage renvoyant différents types d'objets. Mais les utilisateurs sont induits en erreur quant à la nature de ces objets renvoyés. Étant donné que les méthodes exposées par CallObjects et Behaviors correspondent à l'API fournie par Stubs, il est facile de comprendre pourquoi on pourrait supposer qu'il s'agit de _stubs_.

Je suis d'accord avec @jasonkarns. Je viens de tomber dans le même "piège": l'inlining de la déclaration stub ne renvoie pas l'instance stub attendue. Cependant, le chaînage semble fonctionner comme prévu lors de l'utilisation de simulations :

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

Y a-t-il une raison quelconque pour cela?

Je ne sais pas s'il me manque quelque chose, mais le point @froos est-il possible maintenant ? Fallait faire ça :

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

    return fsReaddir(dir);
});

Je voulais faire quelque chose comme :

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

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

Je pense que c'est corrigé maintenant, l'exemple ci-dessous fonctionne comme prévu avec [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 ça échoue toujours de mon côté avec 1.17.7 .
Il prend toujours le dernier returns comme seule valeur de retour, quel que soit le withArgs (comme indiqué par @jasonkarns https://github.com/sinonjs/sinon/issues/176#issuecomment- 78191790).

Ce qui fonctionne pour moi, c'est la réponse de @mantoni https://github.com/sinonjs/sinon/issues/176#issuecomment -33636496, en ne chaînant pas withArgs() .

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

@zurfyx exécutez -vous sur un nœud ou dans un navigateur ? Quelle version de node/navigateur utilisez-vous ? Je ne sais pas si c'est important, mais j'aimerais essayer de reproduire de mon côté.

Salut @valentin-radulescu-hs. Je l'exécute sur Node, en utilisant babel-cli 6.22.2

  • Nœud 6.9.4
  • MNP 3.10.10

Désolé pour la réponse tardive

@zurfyx J'ai essayé de répliquer avec la configuration que vous avez mentionnée en utilisant le même code que celui que j'ai écrit ci- dessus et il sort sur la console sleepy et eating comme prévu. Je ne sais pas pourquoi cela vous cause des problèmes 😢

@zurfyx Juste pour être _totalement_ sûr, avez-vous essayé cela ?

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

La plupart du temps, j'ai des problèmes, c'est parce que la version du package que j'attends n'est pas la même que celle qui est installée.

@ fatso83 Cela ne fonctionne pas non plus. La version de sortie grep est toujours 1.1.7.7 .

Ceci est mon test complet, au cas où cela pourrait aider:

  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'

Je suis capable de reproduire ce comportement en utilisant également sinon.createStubInstance.

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));

Sortir:
2 2

Je pensais sinon.createStubInstance était censé créer un nouvel objet stub. Est-ce incorrect ?

Je ne suis pas tout à fait sûr que cette question appartienne à ce fil, mais cela a certainement quelque chose à voir avec cela. Dans un projet avec sinon 1.17.7 , j'avais l'habitude d'enchaîner plusieurs instructions withArgs , où la dernière était un matcher "grab-all" qui agissait par défaut. Par exemple:

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

Maintenant, j'utilise 4.1.3 et le comportement a changé, il renvoie toujours my-default-value . Était-ce voulu ? Si oui, existe-t-il un moyen de définir une valeur par défaut/de secours dans une chaîne de withArgs ?

Je ne pense pas qu'un changement ait jamais été prévu. Si vous pouvez fournir un correctif pour le
régression n'hésitez pas! Je peux aider à retrouver où cela s'est passé en utilisant got
faire des reproches.

Homme de tanière. 15. janv. 2018, 11.13 skrev David García [email protected] :

Je ne suis pas tout à fait sûr si cette question appartient à ce fil, mais il
a certainement quelque chose à voir avec ça. Dans un projet avec sinon 1.17.7 je
utilisé pour enchaîner plusieurs instructions withArgs, où la dernière était une
matcher "grab-all" qui a agi par défaut. Par exemple:

const s = sinon.stub();s.withArgs(1).returns(1)
.withArgs(2).retourne(2)
.withArgs(sinon.match.any).returns('ma-valeur-par-défaut')
s(1) // 1s(5) // ma-valeur-par-défaut

Maintenant, j'utilise 4.1.3 et le comportement a changé, il revient toujours
ma-valeur-par-défaut. Était-ce voulu ? Si oui, existe-t-il un moyen de définir un
valeur par défaut/de secours dans une chaîne de withArgs ?


Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/sinonjs/sinon/issues/176#issuecomment-357638653 , ou muet
le fil
https://github.com/notifications/unsubscribe-auth/AAluXMzqALJ0JlAM3hUaiK1SSyca9H74ks5tKyS4gaJpZM4AK2eu
.

>

[image : --]

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

@ fatso83 Je l'ai réduit, et apparemment c'était exprès . Pour moi, il semble plus naturel de spécifier un repli dans la dernière instruction withArgs , bien que dans ce cas, il suffit de changer l'ordre et de mettre .withArgs(sinon.match.any) en première position résout le problème

Cette page vous a été utile?
0 / 5 - 0 notes