Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SpyOn a backbone view method using jasmine

Tags:

I have a backbone view and I want to create a test to confirm that a click event on some element will call the function bound to that element. My view is:

PromptView = Backbone.View.extend({
        id:"promptPage",
        attributes:{
            "data-role":"page",
            "data-theme":"a"
        },
        events:{
            "click #btnYes":    "answerYes",
            "tap #btnYes":      "answerYes"
        },
        render: function(){
            $(this.el).html(_.template($('#promptPage-template').html(), this.model.toJSON()));

            return this;
        },
        answerYes: function(){
            alert('yes');
        }
    });

My spec is:

beforeEach(function() {
            model = new PromptModel;
            view = new PromptView({model:model});
            loadFixtures('promptPage.tmpl');
        });

 it("should be able to answer a question with yes", function() {
                var button = $("#btnYes", view.render().el);
                expect(button.length).toBe(1);

                spyOn(view, 'answerYes');

                button.click();
                expect(view.answerYes).toHaveBeenCalled();

            });

However the above view definition creates the answerYes method on the prototype proto , but the spy creates a function on the actual instance in the view, so I end up with a view.answerYes() which is the spy and view.__proto__.answerYes, which is the one I actually want to spy on.

How can I create a spy so that it overrides the answerYes method of the view definition?

like image 371
mishod Avatar asked Oct 26 '11 06:10

mishod


2 Answers

Hi I had today the same problem. And I have just found the solution, after creating the spyed method (answerYes) you have to refresh the events of the view to call that new spyed method ;) :

[...]

    spyOn(view, 'answerYes');
    view.delegateEvents();

    button.click();
    expect(view.answerYes).toHaveBeenCalled();

[...]

More information about delegate events

Have fun!

like image 159
Fernando Gm Avatar answered Sep 22 '22 14:09

Fernando Gm


I generally like to assume that the framework code already does what it ought to and only test my use of it, so I find it acceptable to have a test verifying the events hash. If I find myself duplicating backbone functionality in order to test my thing (like delegating events), then maybe I'm a step closer to integration tests than I really need to be. I also make heavy use of the prototype in order to be super-isolation lady in my unit tests. Of course, it is still important to have an integration layer that does all of that exercising, but I find the feedback loop too long for the test driving phase.

like image 44
crebma Avatar answered Sep 20 '22 14:09

crebma