Search code examples
javascriptangularjsunit-testingjasminemobiscroll

Angular mock method on element


I am testing a directive, where I use the library Mobiscroll. I know that Mobiscroll also has a angular components but I am using older versions of the Mobiscroll library at the moment, so I am not interested in that.

The problem is, I want to test if a method on the element is called, in this case the mobiscroll method. I have the following code the link method of my directive:

link: function (scope, element, attr) {
   var datepicker = element.find("input");

   scope.showDate = function () {           
       datepicker.mobiscroll('show');
   };
}

I want to check in my Jasmine tests, if datepicker.mobiscroll('show') is called. However I cannot set a spy on the element in my tests, because a lookup of the element will not result in the exact same object used in my link method in the directive. For example the following does not work:

    targetElement = $compile(elementBluePrint)($scope);
    rootScope.$apply();
    var target = targetElement.find("input");
    spyOn(target, "mobiscroll").and.callThrough();

Because this does not work, how can I spy on the mobiscroll method in my Angular Jasmine tests?


Solution

  • The common problem with jQuery (and eventually, jqLite) elements is that each element is a new object that wraps DOM element,

    angular.element(element[0]) !== angular.element(element[0])
    

    When one of them is modified (in this case, the property is replaced with mocked function), it doesn't affect the other. For all elements to be affected, their prototype should be mocked instead:

    spyOn(angular.element.prototype, "mobiscroll").and.callThrough();