2014-10-30 5 views
6

Ich versuche, einen Test für das Entprellen von Benutzereingaben in einer Suchanfrage zu schreiben. Die Funktion auf einem Backbone-Ansicht definiert ist:Wie LoDash in Jasmine mit Sinon fakeTimer debunce?

SearchView = Backbone.View.extend({ 
    events: { 
     "input .search-input": "search" 
    }, 

    // init, render, etc. 

    search: _.debounce(function() { 
     this.collection.fetch(); 
    }, 200) 
}); 

Ursprünglich war die Backbone-Bibliothek (v0.9.10) verwendet Unders (v1.4.4), und der Test wurde wie folgt definiert:

describe("SearchView", function() { 
    var view, $viewContainer; 

    beforeEach(function() { 
     appendSetFixtures('<div class="jasmine-container"></div>'); 
     $viewContainer = $(".jasmine-container"); 

     view = new SearchView({ 
      el: $viewContainer 
     }); 
    }); 

    afterEach(function() { 
     view.remove(); 
     view.cleanup(); 
    }); 

    //... 

    describe("wires the search input", function() { 
     var collectionStub, 
      fakeTimer; 

     beforeEach(function() { 
      collectionStub = sinon.stub(
       SearchResultsCollection.prototype, 
       "fetch" 
      );  

      fakeTimer = sinon.useFakeTimers(); 
     }); 

     afterEach(function() { 
      collectionStub.restore(); 
      fakeTimer.restore(); 
     }); 

     it("should not trigger a search before 200ms", function() { 
      fakeTimer.tick(199); 
      expect(collectionStub).not.toHaveBeenCalled(); 
     }); 

     it("should trigger a search after 200ms", function() { 
      fakeTimer.tick(200); 
      expect(collectionStub).toHaveBeenCalled(); 
     }); 
    }); 
}); 

jedoch Jetzt möchte ich LoDash anstelle von Underscore einbinden. Unter Verwendung der neuesten Underscore-Kompatibilität, die auf ihrer Website erstellt wurde (LoDash 2.4.1/Underscore 1.5.6), sind alle meine Tests erfolgreich, mit Ausnahme von denen, die _.debounce verwenden!

Ich habe etwas recherchiert und stieß auf diese relevantissues, um eine LoDash Underscore Build mit runInContext zu erstellen, aber ich habe keine Ahnung, wie man es wegen des Fehlens von Beispielen verwendet. Wie kann ich _.runInContext() in meinen Spezifikationen verwenden, um mit sinon.fakeTimer zu arbeiten?

Antwort

4
SearchView = Backbone.View.extend({ 
    events: { 
     "input .search-input": function() { 
      this.search(); 
     } 
    }, 

    initialize: function() { 
     this.search = _.debounce(this.search, 200); 
    } 

    // init, render, etc. 

    search: function() { 
     this.collection.fetch(); 
    } 
});  

describe("SearchView", function() { 
    var view; 
    var $viewContainer; 
    var clock; 
    var lodash = window._; 

    beforeEach(function() { 
     appendSetFixtures('<div class="jasmine-container"></div>'); 
     $viewContainer = $(".jasmine-container"); 

     clock = sinon.useFakeTimers(); 
     window._ = _.runInContext(window); 

     view = new SearchView({ 
      el: $viewContainer 
     }); 
    }); 

    afterEach(function() { 
     view.remove(); 
     view.cleanup(); 

     clock.restore(); 
     window._ = lodash; 
    }); 

    //... 

    describe("wires the search input", function() { 
     var collectionStub; 

     beforeEach(function() { 
      collectionStub = sinon.stub(
       SearchResultsCollection.prototype, 
       "fetch" 
      );  
     }); 

     afterEach(function() { 
      collectionStub.restore(); 
     }); 

     it("should not trigger a search before 200ms", function() { 
      fakeTimer.tick(199); 
      expect(collectionStub).not.toHaveBeenCalled(); 
     }); 

     it("should trigger a search after 200ms", function() { 
      fakeTimer.tick(200); 
      expect(collectionStub).toHaveBeenCalled(); 
     }); 
    }); 
}); 
+1

Sorry, ich verstehe es nicht, aber Sie setzen' clock = sinon.useFakeTimers(); 'und später Verwende eine andere var 'fakeTimer.tick (199)'. Ein Fehler? – syabro

3

Sie benötigen diese Zeile hinzufügen

_ = _.runInContext(window); 

vor der Schöpfung (nicht Initialisierung) von SearchView oder einem Anruf von _.debounce(). So sollte es gleich nach dem Einschließen Lo-Dash sein.

Auf diese Weise können Sie lodash in globalen Fenster Kontext laufen, so dass Sie von SinonJSsetTimeout überschrieben verwenden können.

+0

Vielen Dank! Ich werde das heute testen und später am Nachmittag nachholen. – SirTophamHatt

+0

'Syntaxfehler:" _ "ist schreibgeschützt –

+0

Wahrscheinlich verwenden Sie' const' anstelle von 'let' –