Sinon: Wrap ES5 Getter und Setter

Erstellt am 3. März 2012  ·  23Kommentare  ·  Quelle: 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

Um Getter und Setter zu unterstützen, müssen Sie ein Object.getOwnPropertyDescriptor(obj, prop) für das Objekt ausführen und dann ein rekursives Object.getPrototypeOf(obj) wenn es nicht existiert, der Deskriptor hat ein 'get' und 'set' Eigenschaft, in der sie definiert sind.

Aber vielleicht möchten Sie nur den Getter oder nur den Setter oder beides verspotten. Wie also spezifizieren Sie das? Einige Optionen:

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

Und haben Sie bereits eine Konvention für den Umgang mit Funktionen, die in der aktuellen Umgebung möglicherweise nicht vorhanden sind? Wenn jemand versucht, dies im IE6 zu tun, was sollte passieren?

Hilfreichster Kommentar

Ein nicht ungewöhnlicher Anwendungsfall ist, dass ein Getter bereitgestellt wird, ein Setter jedoch nicht, wodurch die Eigenschaft schreibgeschützt wird, was für Produktionscode eine gute Idee sein kann, aber beim Testen im Wege steht. Sinon Support-Getter und -Setter zu haben, würde für diesen Anwendungsfall sprechen.

Alle 23 Kommentare

Wenn ich mir Ihre Beispiele ansehe, bin ich mir nicht ganz sicher, ob das Verspotten von Gettern eine gute Testpraxis ist - ich würde annehmen, dass das einfache Festlegen der Eigenschaft für die Dauer des Tests in den meisten Fällen viel bewirken würde (?)

Wie auch immer, was ist, wenn der Stub ein Objekt und keine Funktion ist, wird er als Eigenschaftsdeskriptor behandelt? Etwas wie:

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

Ich bin mir jedoch nicht sicher, wie ich Ihre Erwartungen erfüllen soll. Aber wie gesagt - aber lohnt es sich, falsche Erwartungen bei der Suche nach Immobilien zu stellen? Scheint mir, dass, wenn Sie das brauchen, es vielleicht stattdessen "echte" Methoden sein sollten?

Das Beispiel war einfach. Der eigentliche Code, mit dem ich das versucht habe, hieß get identifier der ein paar Dinge zusammenfügte, von denen einige von Orten kamen, mit denen ich mich im Test nicht beschäftigen wollte, ich wollte das nur bestätigen x.identifier wurde aufgerufen und hat dann die Kontrolle darüber, was zurückgegeben wurde. Im Moment gehe ich mit einem getIdentifier() was in Ordnung ist, aber da wir in Zukunft möglicherweise mehr Getter und Setter für berechnete Eigenschaften sehen, könnte dies etwas sein, das Sinon verarbeiten könnte / sollte?

Da bin ich noch ziemlich unentschlossen. Werde es noch eine Weile ruhen lassen und später entscheiden. Wenn Sie weitere Anregungen/Vorschläge haben, können Sie diese gerne hier notieren.

Ein nicht ungewöhnlicher Anwendungsfall ist, dass ein Getter bereitgestellt wird, ein Setter jedoch nicht, wodurch die Eigenschaft schreibgeschützt wird, was für Produktionscode eine gute Idee sein kann, aber beim Testen im Wege steht. Sinon Support-Getter und -Setter zu haben, würde für diesen Anwendungsfall sprechen.

Im Moment sehe ich keinen Wert darin, Getter und Setter in Sinon zu unterstützen.

Natürlich ist es schon eine Weile her, dass dieses Thema diskutiert wurde, aber diese Funktion wäre sehr hilfreich ...

+1
Ich vermisse es auch. Es wäre besonders nützlich, wenn es mit Komponenten verwendet wird, die als Abstraktionen mit Gettern über eine zugrunde liegende Ressource wie Dateien oder Datenbankobjekte arbeiten. Es wäre schön, diese Getter zu stoppen.

Das würde ich auch gerne wieder öffnen. Dies wäre insbesondere für das Stubbing von Feldern eines umschlossenen Standortobjekts nützlich.

+1 für diese Funktion!

:+1: Ich hatte auch einfach das Bedürfnis nach dieser Funktion.

:+1: Dies muss erneut geöffnet werden. Gerade mit der Verbreitung von ES6 ist dies wichtiger denn je. Ich mag die expectsGet Variante.

+1 Ich stimme @simonzack voll und

+1

Das würde ich auch gerne wieder öffnen. Dies wäre insbesondere für das Stubbing von Feldern eines umschlossenen Standortobjekts nützlich.

Schließt https://github.com/mroderick/wrapple diese Lücke für Sie?

Heutzutage verwende ich Wrapple ziemlich häufig und hatte vergessen, dieses Problem zu kommentieren. Das bedeutet wahrscheinlich, dass Wrapple die Lücke geschlossen hat, wie Sie sagen.

+1 bin gerade über Sinon gestolpert, das Getter-Verspottung nicht unterstützt

Hallo @derwaldgeist , verwendest du die neueste Version von Sinon?

Die neueste Version unterstützt Stubbing-Getter mit sandboxes und sinon.stub .

Alles, was Sie tun müssen, ist die Funktion get verwenden, zum Beispiel:

var myObj = {
    prop: "foo"
};

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

myObj.prop // "bar"

Bitte lassen Sie mich wissen, ob dies zu Ihrem Anwendungsfall passt oder Sie weitere Zweifel haben.

Vielen Dank, dass Sie so schnell zurückgekommen sind, sehr geschätzt.
Ich habe jedoch nicht gefunden, wie man einen so definierten Getter wiederherstellen kann? Ich habe mir sogar den Quellcode von sinon angesehen und konnte keinen Mechanismus erkennen, der beim Aufrufen von get() den ursprünglichen Getter speichert.

Hallo @derwaldgeist ,

Es ist tatsächlich möglich, Getter wiederherzustellen, selbst wenn sie vor dem Stubben undefiniert waren. Alles, was Sie tun müssen, ist die Methode restore im erstellten Stub aufzurufen, zum Beispiel:

var myObj = {
    prop: "foo"
};

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

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

myObj.prop // "baz"

stub.restore();

myObj.prop // "foo"

Wir fügen diese restore Methode hinzu, die entweder in der stub Methode selbst (beim Stuben einer Nicht-Funktionseigenschaft) oder im wrapMethod Dienstprogramm hinzugefügt wird .

Wow, das war schnell. Ich habe das versucht:

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

aber beim Ausführen von restore() heißt es: Cannot redefine property: prop

Woher kommt Ihre Methode createStub ?

@derwaldgeist Das habe ich aus einem Test bekommen, sorry, habe vergessen, es zu bearbeiten. Aber wie auch immer, es ist dasselbe wie sinon.stub .

Können Sie mir sagen, welche Version von Sinon Sie verwenden, damit ich es überprüfen kann?

Ich denke, dass Sie vielleicht noch nicht die neueste Version verwenden, in der wir einen Fehler behoben haben, bei dem Sie Eigenschaften nicht wiederherstellen konnten, da sie ohne configurable: true und wir daher ihre Deskriptoren nicht ändern konnten.

Ich sehe das gleiche wie @derwaldgeist. Ich _glaube_, dass ich v4 verwende, aber einige andere Entwickler haben v1.7 verwendet, daher bin ich mir nicht sicher, was _tatsächlich_ verwendet wird. Ich habe kein sinon.version wo ich zur Laufzeit überprüfen könnte.

@jshado1 Wenn Sie wissen möchten, auf welcher Hauptversion Sie sich befinden, können Sie im Changelog oder Migrationshandbuch sinon.stub({}, 'nonExistingProperty') wirft

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen