How to test LoDash-debounce in Jasmine using Sinon fakeTimer?

I am trying to write a test to debug user input in a search query. The function is defined on the Backbone view:

SearchView = Backbone.View.extend({ events: { "input .search-input": "search" }, // init, render, etc. search: _.debounce(function() { this.collection.fetch(); }, 200) }); 

Backbone (v0.9.10) originally used Underscore (v1.4.4), and the test was defined as follows:

 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(); }); }); }); 

However, now I want to enable LoDash instead of Underscore. Using the latest Underscore compatibility version on my site (LoDash 2.4.1 / Underscore 1.5.6), all my tests pass, except for what is used with _.debounce!

I did some research and stumbled upon these relevant issues to create a LoDash Underscore assembly with runInContext, but I have no idea how to use it due to lack of examples. How to use _.runInContext() in my specifications for working with sinon.fakeTimer ?

+6
source share
2 answers
 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(); }); }); }); 
+4
source

You need to add this line

 _ = _.runInContext(window); 

before creating (not initializing) SearchView or any _.debounce() call. Therefore, it should be immediately after turning on Lo-Dash .

This allows lodash to run in the global window context, so you can use the overridden SinonJS setTimeout value.

+3
source

Source: https://habr.com/ru/post/977506/


All Articles