Sinon: Envelopper les getters et setters ES5

Créé le 3 mars 2012  ·  23Commentaires  ·  Source: sinonjs/sinon

var o = {
  get foobar() { return 'foobar' },
  set foobar(s) { throw 'bzzt!' },
  foo: function() { return 'foo' },
  bar: 'bar'
}; // -> { foobar: [Getter/Setter], foo: [Function], bar: 'bar' }

sinon.mock(o).expects('foobar').returns('woohoo'); // doesn't because sinon.wrapMethod() does an object[property] which accesses the getter which returns a string

Pour prendre en charge les getters et les setters, vous devez faire un Object.getOwnPropertyDescriptor(obj, prop) pour l'objet, puis un Object.getPrototypeOf(obj) récursif s'il n'existe pas, le descripteur a un 'get' et 'set' propriété où ils sont définis.

Mais, vous voudrez peut-être vous moquer du getter ou du setter ou des deux, alors comment spécifier cela? Quelques options :

mock(o).expects('foobar'); // ambiguous, the setter? getter? or both?
mock(o).expects('get foobar'); // ambiguous, there may be a legitimate property named "get foobar"
mock(o).expectsGet('foobar'); // clear but more code in Sinon and more to document ?
mock(o).expectsSet('foobar'); // ditto

Et aussi, avez-vous déjà une convention en place pour gérer les fonctionnalités qui peuvent ne pas être présentes dans l'environnement actuel ? Si quelqu'un essaie de le faire dans IE6, que doit-il se passer ?

Commentaire le plus utile

Un cas d'utilisation qui n'est pas rare est celui où un getter est fourni mais pas un setter, ce qui rend la propriété en lecture seule, ce qui peut être une bonne idée pour le code de production, mais gêner les tests. Avoir les getters et setters du support Sinon parlerait de ce cas d'utilisation.

Tous les 23 commentaires

En regardant vos exemples, je ne suis pas tout à fait sûr que se moquer des getters soit une bonne pratique de test - je suppose que le simple fait de définir la propriété sur une valeur pour la durée du test irait très loin dans la plupart des cas (?)

Quoi qu'il en soit, que se passe-t-il si le stub est un objet au lieu d'une fonction, il sera traité comme un descripteur de propriété ? Quelque chose comme:

stub(o, "foobar", { get: function () { return 42; } });

Je ne sais pas comment répondre à vos attentes cependant. Mais comme je l'ai dit, est-ce que cela vaut la peine de mettre des attentes fictives sur les recherches de propriétés ? Il me semble que si vous en avez besoin, peut-être devraient-ils plutôt être des méthodes "réelles"?

L'exemple était simpliste. Le vrai code sur lequel j'essayais de faire cela s'appelait get identifier qui ajoutait quelques éléments ensemble, dont certains provenaient d'endroits avec lesquels je ne voulais pas m'embêter dans le test, je voulais juste confirmer que x.identifier été accédé et a ensuite le contrôle sur ce qui a été renvoyé. Pour l'instant, je vais avec un getIdentifier() ce qui est bien, mais étant donné que nous verrons peut-être plus de getters et setters dans le futur pour les propriétés calculées, cela pourrait être quelque chose que Sinon pourrait / devrait gérer?

Encore un peu indécis à ce sujet. Je le laisserai reposer un moment et je déciderai plus tard. Si vous avez d'autres commentaires/suggestions, n'hésitez pas à les noter ici.

Un cas d'utilisation qui n'est pas rare est celui où un getter est fourni mais pas un setter, ce qui rend la propriété en lecture seule, ce qui peut être une bonne idée pour le code de production, mais gêner les tests. Avoir les getters et setters du support Sinon parlerait de ce cas d'utilisation.

Pour le moment, je ne vois pas l'intérêt de prendre en charge les getters et setters dans Sinon.

évidemment, cela fait un moment que cette question n'a pas été abordée, mais cette fonctionnalité serait très utile...

+1
ça me manque aussi. Il serait particulièrement utile lorsqu'il est utilisé avec des composants qui fonctionnent comme des abstractions avec des getters sur une ressource sous-jacente, comme des fichiers ou des objets de base de données. Ce serait bien de pouvoir écraser ces getters.

J'aimerais aussi que cela rouvre. Cela serait utile spécifiquement pour les champs de remplacement d'un objet de localisation enveloppé.

+1 pour cette fonctionnalité !

:+1: Je viens aussi de ressentir le besoin de cette fonctionnalité.

:+1: Cela doit être rouvert. Surtout avec l'essor de l'ES6, c'est plus important que jamais. J'aime la variante expectsGet .

+1 Je suis entièrement d'accord avec @simonzack

+1

J'aimerais aussi que cela rouvre. Cela serait utile spécifiquement pour les champs de remplacement d'un objet de localisation enveloppé.

https://github.com/mroderick/wrapple comble-t-il cet écart pour vous ?

De nos jours, j'utilise beaucoup wrapple et j'avais oublié de commenter ce problème. Cela signifie probablement que wrapple a comblé l'écart comme vous le dites.

+1 vient de tomber sur sinon ne prenant pas en charge la moquerie getter

Salut @derwaldgeist , utilisez-vous la dernière version de Sinon ?

Le dernier supporte les getters stub avec à la fois sandboxes et sinon.stub .

Tout ce que vous avez à faire est d'utiliser la fonction get , par exemple :

var myObj = {
    prop: "foo"
};

createStub(myObj, "prop").get(function getterFn() {
    return "bar";
});

myObj.prop // "bar"

Veuillez me faire savoir si cela convient à votre cas d'utilisation ou si vous avez d'autres doutes.

Merci d'être revenu aussi vite, très apprécié.
Cependant, je n'ai pas trouvé comment vous pouvez restaurer un getter qui a été défini de cette façon? J'ai même regardé le code source de sinon et je n'ai pas pu voir de mécanisme qui stocke le getter d'origine lors de l'appel de get().

Salut @derwaldgeist ,

Il est en effet possible de restaurer des getters, même s'ils n'étaient pas définis avant d'être stub. Tout ce que vous avez à faire est d'appeler la méthode restore dans le stub créé, par exemple :

var myObj = {
    prop: "foo"
};

var stub = createStub(myObj, "prop");

stub.get(function getterFn() {
    return "baz";
});

myObj.prop // "baz"

stub.restore();

myObj.prop // "foo"

Nous ajoutons cette méthode restore soit dans la méthode dans l'utilitaire wrapMethod .

Wow, c'était rapide. J'ai essayé ceci :

 const stub = sinon.stub(myObj, 'prop');
 stub.get(() => ({}));
  ...
 stub.restore();

mais lors de l'exécution de restore(), il dit : Cannot redefine property: prop

D'où vient votre méthode createStub ?

@derwaldgeist J'ai obtenu cela d'un test, désolé, j'ai oublié de le modifier. Mais de toute façon, c'est la même chose que sinon.stub .

Pouvez-vous me dire quelle version de sinon utilisez-vous pour que je puisse la vérifier ?

Je pense que vous n'utilisez peut-être pas encore la dernière version dans laquelle nous avons corrigé un bogue où vous ne pouviez pas restaurer les propriétés car elles étaient définies sans configurable: true et nous n'avons donc pas pu modifier leurs descripteurs.

Je vois la même chose que @derwaldgeist. Je pense que j'utilise la v4, mais d'autres développeurs utilisaient la v1.7, donc je ne suis pas sûr de ce qui est _réellement_ utilisé. Je n'ai pas vu de sinon.version où je pourrais vérifier au moment de l'exécution.

@jshado1 Si vous voulez savoir sur quelle version majeure vous vous trouvez, vous pouvez vous référer au journal des modifications ou au guide de migration et tester les modifications de rupture. Pour la version 4, vous pouvez affirmer que sinon.stub({}, 'nonExistingProperty') jette

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