2014-06-18 18 views
22

Ich versuche, ein React Komponentenverfahren zu Testzwecken Stummel:Stubbing ein Verfahren Reagieren Komponente mit Sinon

var Comp = React.createClass({ 
    displayName: "Comp", 

    plop: function() { 
    console.log("plop"); 
    }, 

    render: function() { 
    this.plop(); 
    return React.DOM.div(null, "foo"); 
    } 
}); 

var stub = sinon.stub(Comp.type.prototype, "plop"); 
React.addons.TestUtils.renderIntoDocument(Comp()); 
sinon.assert.called(stub); // throws 

Diese traurig Druck „Plopp“ auf der Konsole hält ... und die Behauptung fehlschlägt.

Hinweis: Direktes Stubben der Spec-Objekt-Methode funktioniert, aber dann müssen Sie den Komponentenkonstruktor und die Spezifikation separat exportieren, so dass sie beide in Tests verfügbar sind ... Außerdem müssten Sie die Spezifikation vor dem Erstellen der Komponentenklasse; nicht so bequem:

var CompSpec = { 
    displayName: "Comp", 

    plop: function() { 
    console.log("plop"); 
    }, 

    render: function() { 
    this.plop(); 
    return React.DOM.div("foo"); 
    } 
}; 

var stub = sinon.stub(CompSpec, "plop"); 
var Comp = React.createClass(CompSpec); 
React.addons.TestUtils.renderIntoDocument(Comp()); 

// plop() is properly stubbed, so you can 
sinon.assert.called(stub); // pass 

Können Sie sich eine andere Strategie ein leicht Stummel Komponentenmethode reagieren?

Antwort

29

Du läufst gegen das Reagieren auto-binding feature, die die .bind(this)-Caches, die sich um Ihre Klasse gewickelt Methoden.

var Comp = React.createClass({ 
    displayName: "Comp", 

    plop: function() { 
    console.log("plop"); 
    }, 

    render: function() { 
    this.plop(); 
    return React.DOM.div(null, "foo"); 
    } 
}); 

// with older versions of React, you may need to use 
// Comp.type.prototype instead of Comp.prototype 
var stub = sinon.stub(Comp.prototype.__reactAutoBindMap, "plop"); // <-- 
React.addons.TestUtils.renderIntoDocument(React.createElement(Comp)); 
sinon.assert.called(stub); // passes 
+0

per http://stackoverflow.com/questions/8825870/sinon-js-attempted-to-wrap-ajax-which-isready binden -wrapped Ich muss dann die Wrapped-Funktionen wiederherstellen, wenn ich sie in einem anderen Test erneut einpacken möchte. Die Antwort dort funktioniert nicht. Wie würdest du das hier mit deiner Lösung machen? – YPCrumble

+0

@YPCrumble - Sie könnten die ursprüngliche Funktion einer Variable im beforeEach zuweisen, dann den Stub wie oben und dann die ursprüngliche Funktion auf die Variable zurücksetzen, der Sie im beforeEach zugewiesen haben. var originalFunc; before (function() { originalFunc = Comp.type.prototype .__ reactAutoBindMap.plop; var stub = sinon.stub (Comp.type.prototype .__ reactAutoBindMap "Plopp"); React.addons.TestUtils. renderIntoDocument (React.createElement (Comp)); sinon.assert.genannt (stub); // übergibt }); afterEach (Funktion() { Comp.type.prototype .__ reactAutoBindMap.plop = originalFunc; }); – alengel

+1

@danvk Ich glaube, das ist jetzt mit React v15 veraltet - irgendwelche Vorschläge, was Sie weiter verwenden? – YPCrumble

5

Welches Testframework verwenden Sie?

Wenn Sie Jasmin verwenden, habe ich jasmine-react als eine nützliche Bibliothek zum Ausspionieren von React-Methoden sowie zum Ersetzen von Komponenten durch Teststubs gefunden.

In diesem Fall können Sie Ihre Methode leicht außerhalb der Komponentendefinition ausspionieren.

//Component Definition 
var Comp = React.createClass({ 

    displayName: "Comp", 

    plop: function() { 
     console.log("plop"); 
    }, 

    render: function() { 
     this.plop(); 
     return React.DOM.div(null, "foo"); 
    } 
}); 

//test 
it("should call plop method on render", function(){ 
    //spy on method 
    jasmineReact.spyOnClass(Comp, "plop"); 
    React.addons.TestUtils.renderIntoDocument(Comp()); 
    expect(Comp.plop).toHaveBeenCalled(); 
}) 

jasmineReact.spyOnClass gibt einen gewöhnlichen Jasmin Spion, der Sie Anrufe zu ihm und seine Argumente verfolgen können.

Wenn Sie möchten, um tatsächlich die Methode Stummel und es etwas zurückgeben zu machen, können Sie etwas tun, wie jasmineReact.spyOnClass(Comp, "plop").andReturn('something')

Alternativ Facebook hat vor kurzem einen Test-Framework gestartet Jest (auch hat Jasmin als Abhängigkeit), die sie selbst nutzen zum Testen von React-Komponenten. Komponentemethoden können mit diesem Framework einfach geblockt werden. Das sieht aus wie seinen Wert als auch Check-out, aber wahrscheinlich kommt in seine eigene ein bisschen mehr, wenn Sie Ihre Komponenten innerhalb Commonjs Module schreiben

+0

Bitte beachten Sie auf npm dies ‚Jasmin-reagieren-Helfer‘, nicht ‚Jasmin reagieren‘ –

+1

Hat diese Arbeit, wenn: Sie können Ihren Code zu arbeiten, indem sie stubbing die im Cache gespeicherte Version des Verfahrens in der Reaktion __reactAutoBindMap erhalten Erstellen von Komponenten mit dem ES6-Klassenstil? –

+0

@DanielBillingham - ziemlich sicher, es funktioniert nur, wenn Sie im Konstruktor, nicht Pfeilstil – ptim

Verwandte Themen