Jasmine simula los métodos encadenados con Karma y Angular.

Quiero burlarme de angular.element . Y quiero asegurar que angular.element haya sido llamado una cierta cantidad de veces y que anguler.element.attr haya sido llamado.

Tengo el siguiente código:

 var things = $scope.getThings(); for (var i = 0; i < things.length; i++) { if (things[i].type == "xyz") { angular.element("#thing-" + things[i].id) .attr("foo", things[i].bar); }; }; 

En mi prueba tengo:

 var things = [ { id: 1, type: "xyz", bar: 10 }, { id: 2, type: "abc", bar: 33 } ]; spyOn($rootScope, "getThings").and.returnValue(things); spyOn(angular, "element").and.returnValue(); $rootScope.doThings(); // call controller method expect(angular.element.calls.count()).toBe(1); 

Pero da el siguiente error:

TypeError: undefined no es un objeto (evaluando ‘angular.element (“# thing-” + things [i] .id) .attr’)

También quiero que mi examen tenga algo como:

 expect(angular.element.attr.calls.count()).toBe(1); expect(angular.element.attr).tohaveBeenCalledWith("foo", things[0].bar); 

La forma en que se deben espiar o simular los métodos encadenados depende únicamente de cómo se definan en los objetos espiados.

En el caso de Angular jqLite, o en su caso, jQuery (ambos se sirven de forma transparente a través de angular.element fachada) los métodos encadenados se definen en el prototipo de constructor, que se expone en la función de fábrica como angular.element.prototype o jQuery.prototype ( angular.element === jQuery cuando se carga jQuery).

Para espiar tanto en angular.element como en angular.element(...).attr debe ser:

 spyOn(angular, 'element').and.callThrough(); spyOn(angular.element.prototype, 'attr').and.callThrough(); ... expect(angular.element).toHaveBeenCalled(); expect(angular.element.prototype.attr).toHaveBeenCalled(); 

callThrough es importante en este caso porque, de lo contrario, toda la cadena debe ser tachada manualmente.

Intenta añadir este código:

 var spy; beforeEach(function() { spy = spyOn(angular, 'element')..... }); afterEach(function() { spy.andCallThrough(); }); 

Puedes encontrar más en: Jasmin docs