Sinon: Spys thisValue zeigt beim Ausspionieren des Konstruktors nicht auf eine Instanz

Erstellt am 9. Feb. 2018  ·  10Kommentare  ·  Quelle: sinonjs/sinon

Dieses Snippet funktioniert gut mit Sinon 2.0.0, schlägt jedoch mit Sinon 4.2.2 fehl:

it('returns correct thisValue', function() {
    window.SomeClass = function() {
        this.counter = 0;
        this.inc = function() {
            this.counter++;
        };
        this.getCounter = function() {
            return this.counter;
        };
    };

    var spy = sinon.spy(window, 'SomeClass');
    var some = new window.SomeClass();
    some.inc();

    expect(spy.thisValues[0].counter).toEqual(1);
    expect(spy.thisValues[0].getCounter()).toEqual(1);
    some.inc();
    expect(spy.thisValues[0].counter).toEqual(2);
    expect(spy.thisValues[0].getCounter()).toEqual(2);
});

Es sieht so aus, als ob das thisValues[0] -Objekt ein Proxy ist und sich nicht auf die tatsächliche Instanz von some bezieht.

Dies ist der Fehler bei Sinon 4.2.2:

Expected undefined to equal 1
TypeError: undefined is not a function (evaluating 'spy.thisValues[0].getCounter()')
Bug Medium Help wanted Regression hacktoberfest pinned

Hilfreichster Kommentar

Auch wenn es nicht häufig verwendet wird oder zumindest nicht häufig gemeldet wird, möchte ich, dass diese Regression behoben wird.

Alle 10 Kommentare

Dies ist ein guter Kandidat für die Verwendung von git bisect um festzustellen, wann das Verhalten geändert wurde, was möglicherweise einen Hinweis darauf gibt, ob die Änderung beabsichtigt war (eine Funktion) oder nicht (ein Fehler).

Es sollte nicht so schwierig sein, das bereitgestellte Beispiel @ PVince81 in ein kleines git bisect run .

Wenn Sie nicht wissen, wie man git bisect , ist dies eine ausgezeichnete Gelegenheit, um ein Level aufzusteigen!

http://www.marclittlemore.com/how-to-find-bugs-using-git-bisect-with-this-easy-guide/

Oh, ich liebe es zu halbieren! Ich werde mich darum kümmern ..

Los geht's: 911c498dc14dc4034ba019526bf58f8b24d77da0 Spion telefoniert mit new (# 1626)

Danke dafür, @ PVince81! Ein Fix möchte möglicherweise auch # 1265 überprüfen, da er berührt, welche Änderungen erforderlich sind, um das Ausspionieren von Konstruktoren zu unterstützen.

Wenn ein Objekt nicht mit new , wird diese Methode aufgerufen, die den Inhalt von thisValue und der Erweiterung thisValues ändert. Im Gegensatz dazu lässt die Methode , thisValue unverändert.

Wenn man bedenkt, dass unser Code nur eine einzige Verwendung davon hat, wäre ich eher versucht, den schnellen Weg zu gehen und unseren einzigen Test zu ändern, der dies ausgelöst hat, da ich keine Zeit habe, mich mit den Interna von sinon zu beschäftigen und mich nicht qualifiziert zu fühlen potenziell bahnbrechende Änderungen vornehmen

Da sich nicht so viele Leute über dieses Problem beschwert zu haben scheinen, testen die Leute dies normalerweise nicht auf diese Weise und eine Lösung ist es nicht wert (nur eine Beobachtung, bis die Betreuer entscheiden).

Auch wenn es nicht häufig verwendet wird oder zumindest nicht häufig gemeldet wird, möchte ich, dass diese Regression behoben wird.

Gibt es Pläne, dieses Problem zu beheben?

@ ivan-zakharchuk Wenn sich niemand freiwillig meldet, gibt es keine Pläne, nein. Wenn du es reparieren willst, gibt es einen natürlichen nächsten Schritt, der gemacht werden könnte ;-)

Dies ist das beleidigende Commit: https://github.com/sinonjs/sinon/issues/1683#issuecomment -364794930

Um nur zu sagen, ich habe lange versucht, eine Lösung dafür zu finden, war aber erfolglos. Es ist ein Albtraum von this Werten. Das Kernproblem scheint zu sein , dass new die bereitgestellte Funktion ing hier von Natur aus erstellt einem brandneuen this , während thisValues[0] (wie in der ursprünglichen Nachricht verwendet) bezieht sich auf den this erstellt durch die new im Test selbst (dh die var some = new window.SomeClass(); ) - sehr verwirrend, wie ich weiß.

Im Wesentlichen bedeutet dies zu beheben, dass versucht wird, es in beide Richtungen zu haben - das Aufrufen von new bedeutet absolut ein neues this , aber wir müssen es zweimal aufrufen (dh eines im OP-Test und eines in proxy-invoke.js ), um ES6 zu erfüllen. Sie werden also immer zwei this es haben. Das einzige, woran ich denken konnte, war, die Funktionen von einem this an das andere zu binden, aber das war selbst dafür zu hackig und hat ein paar andere Dinge kaputt gemacht.

Ich hoffe, dass das oben Gesagte Sinn macht. Bitte zögern Sie nicht, dies zu korrigieren oder um Klarstellung zu bitten. Hier finden Sie eine Auffrischung darüber, was das Schlüsselwort new tatsächlich bewirkt - TLDR erstellt ein neues Objekt und macht es zu this , unabhängig vom Kontext.

Wie auch immer, eine Sache, die mir aufgefallen ist, war, dass 911c498 (das Commit, das die Regression eingeführt hat) keinen Test enthält, der das angesprochene Problem abdeckt - die Anforderung, new mit ES6-Klassen zu verwenden. Dies liegt wahrscheinlich daran, dass die Flusenoptionen für die Tests das Schlüsselwort class nicht zulassen, da sie nur ES5 berücksichtigen. Ich habe ein Commit, das einen Test hinzufügt, damit ein zukünftiger Fix für das aktuelle Problem den Fix in 911c498 nicht aufhebt - ich kann ihn PR, wenn Interesse besteht.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen