我想嘲笑angular.element。我想确保angular.element已经被调用了一定的次数,并且也anguler.element.attr已经被调用了。
angular.element
anguler.element.attr
我有以下代码:
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); }; };
在我的测试中,我有:
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);
但是它给出了以下错误:
TypeError:未定义不是对象(评估’angular.element(“#thing-” + Things [i] .id).attr’)
我还希望我的测试具有以下内容:
expect(angular.element.attr.calls.count()).toBe(1); expect(angular.element.attr).tohaveBeenCalledWith("foo", things[0].bar);
监视或模拟链接方法的方式仅取决于如何在被监视对象上定义它们。
在Angular jqLite的情况下,或者在您的情况下,jQuery(都是通过angular.element立面透明地提供服务)的链接方法是在构造函数原型上定义的,该方法在工厂函数中显示为angular.element.prototypeor jQuery.prototype(或angular.element === jQuery在加载jQuery时)。
angular.element.prototype
jQuery.prototype
angular.element === jQuery
为了监视两者angular.element,angular.element(...).attr应该是:
angular.element(...).attr
spyOn(angular, 'element').and.callThrough(); spyOn(angular.element.prototype, 'attr').and.callThrough(); ... expect(angular.element).toHaveBeenCalled(); expect(angular.element.prototype.attr).toHaveBeenCalled();
callThrough 在这种情况下非常重要,因为否则整个链都应该手动存根。
callThrough