Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Browser page keeps refreshing when testing Backbone views with Jasmine

Running the following Jasmine test(1), the test is successfully performed but I face the recursive loading of the main test page.

Here is my test (1) and here the module on which I am running the test (2):

Any ideas? How can I fix the issue?

P.S.:
The issue regard just Chrome and Safari Browser.
Here is an example: jsfiddle.net/shioyama/EXvZY


(1)

describe('When Submit button handler fired', function () {
    beforeEach(function () {
        spyOn(MyView.prototype, 'submitForm');
        this.view = new MyView();
        this.view.render();
        this.view.$el.find('form').submit();
    });

    it('submitForm should be called', function () {
        expect(MyView.prototype.submitForm).toHaveBeenCalled();
    });
});

(2)

var MyView = Backbone.View.extend({
    events: {
        'submit form' : 'submitForm'
    },

    submitForm: function (event) {
        event.preventDefault();
        // some code
    }
});
like image 604
Lorraine Bernard Avatar asked Oct 23 '22 13:10

Lorraine Bernard


1 Answers

Backbone uses delegate events, which are bound when the view is created. Your view.el does not contain a form when it is created, but instead you're creating one in the render method. That's why the submit delegate event does not get bound, and instead you're submitting the form on the page. That form submit goes to the same URL, which triggers the Jasmine suite to be run again, resulting in a loop.

If you modify your code a bit, you'll find that this version works, as the <form> element exists before the view is generated.

var MyView = Backbone.View.extend({
    events: {
        'submit form' : 'submitForm'
    },

    submitForm: function (event) {
        event.preventDefault();
        // some code
    }
});

//start test runner right after we're done defining our tests in this script
window.setTimeout( function(){
    jasmine.getEnv().addReporter(new jasmine.TrivialReporter());
    jasmine.getEnv().execute();
}, 0 );

//TESTS GO HERE
describe('When Submit button handler fired', function () {
    beforeEach(function () {
        spyOn(MyView.prototype, 'submitForm').andCallThrough();
        this.view = new MyView({
            el: $('<div><form><input type="submit" value="Submit" /></form></div>')
        });
        this.view.$el.find('form').submit();
    });

    it('submitForm should be called', function () {
        expect(MyView.prototype.submitForm).toHaveBeenCalled();
    });
});​

like image 53
Lauri Piispanen Avatar answered Oct 30 '22 00:10

Lauri Piispanen