How to assert a spy is invoked with event on click using jasmine?
Asked Answered
M

2

13

I'm writing a simple click handler and need the event passed in (like so)

Thing = function($){

    var MyObject = function(opts){
        this.opts = opts;
    };

    MyObject.prototype.createSomething = function(){
        var that = this;
        $('#some_dom_element').live('click', function(e) {
            that.doStuff(e);
        });
    };

    MyObject.prototype.doStuff = function(e) {
        //do some javascript stuff ...
        e.preventDefault();
    };

    return MyObject;

}(jQuery);

Currently in my jasmine spec I've got something to spy on the function I expect gets invoked (but since it's called with e -not without args- my assertion is failing)

    it ("live click handler added to the dom element", function(){
        var doSpy = spyOn(sut, 'doStuff');
        sut.createSomething();
        $("#some_dom_element").trigger('click');
        expect(doSpy).toHaveBeenCalledWith();
    });

How can I correct this "toHaveBeenCalledWith" to work as I expect?


UPDATE

I couldn't get the accepted answer to work as is but I was able to alter it just a little and the below is my 100% working example

    it ("should prevent default on click", function(){
        var event = {
            type: 'click',
            preventDefault: function () {}
        };
        var preventDefaultSpy = spyOn(event, 'preventDefault');
        sut.createSomething();
        $("#some_dom_element").trigger(event);
        expect(preventDefaultSpy).toHaveBeenCalledWith();
    });
Mellifluous answered 17/7, 2012 at 19:5 Comment(0)
W
18

You have to trigger your own event passing a spy for the stopPropagation method, cause you wanna test if the event was stopped.

var event = {
    type: 'click',
    stopPropagation: function(){}
}
var spy = spyOn(event, 'stopPropagation');
$('#some_dom_element').trigger(event);
expect(spy).toHaveBeenCalled();

Note: there is code smell when you spy on the object you want to test, because you start to test the inner behavior of your class. Think about your function as a black box and test only the things you put in and get out. In your case, renaming the function in will break the test, while the code is still valid.

Waver answered 18/7, 2012 at 19:7 Comment(1)
how to assert custom events in jasmine? like if the event name is "create" means how can we assert it.Chock
S
2

If you can't use jQuery you may use dispatchEvent and check its return value (based on this answer).

const domElem = document.getElementById('some_dom_element');
const clickEvent = new MouseEvent('click', {
  view: window,
  bubbles: true,
  cancelable: true
});

const cancelled = !domElem.dispatchEvent(clickEvent);
expect(cancelled).toBeTruthy();
Spinneret answered 8/11, 2019 at 13:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.