Sinon: createStubInstance ne remplace pas ses propres propriétés ou quoi que ce soit hérité

Créé le 23 janv. 2021  ·  3Commentaires  ·  Source: sinonjs/sinon

Décrivez le bogue
createStubInstance ignore ses propres propriétés et, sur une super classe, ignore ses méthodes et propriétés héritées

Reproduire

class SubTest {
  name;

  constructor({ name }) { this.name = name }

  something() {}
}

export default class SuperTest extends SubTest {
  description;

  constructor(...props) {
    super(props);
    this.description = props.description;
  }

  noop() {}
}
import sinon from 'sinon';
import SuperTest from './SuperTest.js';

sinon.createStubInstance(SuperTest, {
  description: 'Lorem Ipsum',
  name: 'Foobar',
  noop() {},
  something() {},
});
Error: Cannot stub description. Property does not exist!
    at …/sinon/lib/sinon/stub.js:129:19
    at Array.forEach (<anonymous>)
    at stub.createStubInstance (…/sinon/lib/sinon/stub.js:120:5)

après avoir commenté description: 'Lorem Ipsum', :

Error: Cannot stub name. Property does not exist!
    at …/sinon/lib/sinon/stub.js:129:19
    at Array.forEach (<anonymous>)
    at stub.createStubInstance (…/sinon/lib/sinon/stub.js:120:5)

après avoir également commenté name: 'Foobar', :

Error: Cannot stub something. Property does not exist!
    at …/sinon/lib/sinon/stub.js:129:19
    at Array.forEach (<anonymous>)
    at stub.createStubInstance (…/sinon/lib/sinon/stub.js:120:5)

Avec seulement noop() {} dans les remplacements, cela fonctionne.

Comportement prévisible
Je m'attends createStubInstance ce que

Contexte (veuillez compléter les informations suivantes) :

  • Version de la bibliothèque : [email protected]
  • Environnement:
    macOS 11.1
    nœud 15.6.0
    npm 7.4
  • Autres bibliothèques que vous utilisez :
    chaï 4.2.0
    sinon-chai 3.5.0

EDIT : à l'origine, j'ai trop simplifié le test ci-dessus et omis super() , mais cela n'a eu aucun effet sur le comportement de sinon. Le test ci-dessus est corrigé.

Easy Documentation Help wanted

Tous les 3 commentaires

Merci d'avoir soulevé cela. Il y a plusieurs choses qui ne vont pas ou qui sont mal comprises ici :

  • Le deuxième argument sur createStubInstance n'est pas documenté (je n'étais même pas au courant 😄).
  • La documentation indique explicitement que

    La fonction constructeur donnée n'est pas invoquée.

    Ainsi, l'hypothèse selon laquelle il peut être utilisé pour passer des arguments initiaux ne peut pas fonctionner.

  • L'implémentation existante de cette fonctionnalité non documentée fait ceci :

    • Lancé si la propriété n'est pas remplaçable car elle n'existe pas sur l' instance de stub . C'est ce qui se passe dans votre cas. Le constructeur n'a pas été appelé et donc vos propriétés "membre" n'existent pas.

    • Si un override donné est un stub, remplacez le stub par défaut par celui donné (par exemple { something: sinon.stub() } ).

    • Sinon, faites en sorte que le stub par défaut renvoie la valeur de propriété donnée (par exemple, { something: 42 } ).

Cela nécessite clairement une meilleure documentation, mais ce n'est pas un bogue.


Comment faire fonctionner votre cas d'utilisation :

Notez que vous créez un nouvel objet à partir du prototype "classe". Vous ne créez pas réellement une instance de la classe car le constructeur n'est pas appelé. Fondamentalement, la valeur de retour de createStubInstance juste la même interface que votre classe avec toutes les fonctions remplacées par des stubs. Par conséquent, si vous avez besoin de propriétés sur cette instance de stub, vous pouvez simplement les affecter.

Merci pour votre réponse rapide!

Notez que vous créez un nouvel objet à partir du prototype "classe". Vous ne créez pas réellement une instance de la classe car le constructeur n'est pas appelé. Fondamentalement, la valeur de retour de createStubInstance juste la même interface que votre classe avec toutes les fonctions remplacées par des stubs. Par conséquent, si vous avez besoin de propriétés sur cette instance de stub, vous pouvez simplement les affecter.

Cela vaut-il la peine de prendre en charge cela dans createStubInstance ?

function createStubInstance (…) {
  // …
  return Object.assign(stubbedInstance, propertyValuePairs); // anything it doesn't recognise
}

@jshado1 Bien sûr, nous pourrions le faire. Si cette fonctionnalité vous intéresse, n'hésitez pas à envoyer une pull request 🙂

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