简体   繁体   中英

Jasmine - spying on a function called within EXTJS listener

What I want to achieve is to test, if clicking a button fires a proper function. I will present you some code to see:

Controller:

init: function() {
        this.control({
            'locationSettingsWest #buttonAddLocation' : {
                click: this.settings.addLocation
            }
        });
},
settings: {
    addLocation: function() {
            console.log('addLocation called. scope below should be controller');
            console.log(this);
        }
}

And finaly the tests:

// code1
it('Location add button clicked, addLocation called', function() {
            console.log(tmpObj.controller); // controller declared, fine
            var scope = tmpObj.controller,
                spy = spyOn(scope.settings, 'addLocation').and.callThrough();
            tmpObj.contentWest.down('#buttonAddLocation').fireEvent('click'); // button clicked, log 'addLocation called' shows in console (dunno why twice, but shows)
            expect(spy).toHaveBeenCalled()
        });

Result is failure, jasmine says Expected spy addLocation to have been called. When I call the function directly, like below, it works

// code2
it('Location add button clicked, addLocation called', function() {
            console.log(tmpObj.controller); // controller declared, fine
            var scope = tmpObj.controller,
                spy = spyOn(scope.settings, 'addLocation').and.callThrough();
            scope.settings.addLocation.call(tmpObj.controller);
            //tmpObj.contentWest.down('#buttonAddLocation').fireEvent('click'); // button clicked, log 'addLocation called' shows in console (dunno why twice, but shows)
            expect(spy).toHaveBeenCalled()
        });

So, what I want to achieve is to test, if clicking a button fires a proper function.

What I also tried:

// doing a call with scope on fireEvent
tmpObj.contentWest.down('#buttonAddLocation').fireEvent.call(scope, 'click');

// spying without .and.callThrough() (which I discovered later)
spyOn(scope.settings, 'addLocation')

// looking for calls history in ...addLocation.calls ...
console.log(scope.settings.addLocation.calls);
console.log(scope.settings.addLocation.calls.any());
// ... which worked with code2 but not with code1

// and many other combinations...

Thanks!

jasmine 2.3.4 extjs 4.2.1

You need to call spyOn() before the Controller is initialized and handler references are resolved:

describe("click tests", function() {
    var controller;

    beforeEach(function() {
        controller = new My.app.Controller(...);

        for (var fn in controller.settings) {
            spyOn(controller.settings, fn).and.callThrough();
        }

        controller.init();
    });

    it("should do something on click", function() {
        ...
    });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM