Search code examples
javascriptjqueryangularjsjasminejasmine-jquery

How to spyon jquery function inside angular directive in Jasmine


Directive

         link(scope, element, attrs, ctrl) {    

            element.mouseover(function() {
                $(element).tooltip('show');
            });
            $(element).hover(MuiBootstrap.adjustTooltips);
        }

Jasmine test

       it('should show tooltip on mouseover', function () {
         var spy = spyOn(element, 'mouseover');
         $(element).trigger('mouseover');
         expect(spy).toHaveBeenCalled();
       });

Above jasmine test is getting failed Error: Uncaught Expected spy tooltip to have been called.


Solution

  • It will not work since you try to spy on mouseover method which is called only once in directive link function and you install spy on this method after it has been already called - the moment you install spy spied function already has been called so spy is not aware of this.
    I suggest to not test if mouseover itself is called but if mouseover callback is called when event is triggered - which you actually do because you spy on tooltip method (your error message suggests that you spy on tooltip method). So just remove this test since it's pointles. I assume you want to test if mouseover callback has been called not if mouseover method has been called - these two are not the same.

    Answer update: To test mouseover callback you can define this callback on directive scope:

    link(scope, element, attrs, ctrl) {    
        scope.mouseoverCallback = function() {
            $(element).tooltip('show');
        };
        element.mouseover(scope.mouseoverCallback);
    }
    

    and then install spy directly on it:

     it('should call mouseover callback', function () {
         var yourDirectiveScope = element.scope();
         var spy = spyOn(yourDirectiveScope, 'mouseoverCallback').and.callThrough();
         element.triggerHandler('mouseover');
         expect(yourDirectiveScope.mouseoverCallback).toHaveBeenCalled();
     });