Angular:如何监视$element.on

Angular: How to spy on $element.on

本文关键字:element on 监视 何监视 Angular      更新时间:2023-09-26

我有一个指令,它在link函数中执行类似的操作

angular.module('myApp')
    .directive('barFoo', function() {
        return {
            restrict: 'E',
            link: function (scope, element) {
                element.on('click', ....);
            }
        };
    });

现在我想在我的单元测试中验证它是否正确调用on

element = angular.element('<bar-foo></bar-foo>');
$compile(element)(scope);
spyOn(element, 'on');
...
expect(element.on).toHaveBeenCalled();

它告诉我间谍不叫。根据我在网上的发现,angular/jquery每次都会围绕DOM元素创建一个新的包装器。这意味着我的指令中的element与我的规范文件中的元素不同。很可能(未验证)element[0]可能是相同的。我还试图监视angular.element

var mockEl = { on: angular.noop };
spyOn(angular, 'element').andReturn(mockEl);
spyOn(mockEl, 'on');

但这似乎比修复的要多(例如,我还需要像isloateScope这样的函数)。

不管怎样,有没有什么简单的方法可以监视指令中使用的元素的on函数?

链接功能可以单独测试

element = angular.element('<bar-foo');
spyOn(element, 'on');
BarFooDirective[0].link(scope, element);
expect(element.on).toHaveBeenCalled();

如果它足够简单(远离属性、必需的控制器、依赖项),否则规范将导致比它所能解决的更多的问题。

否则,它可以像框架一样进行测试

element = angular.element('<bar-foo');
expect(angular.element._data(element[0]).events.click).toBeDefined();

对于可能在自身或子指令中定义了多个click侦听器的真实指令,仅确保侦听器的存在是不够的。一般来说,您可能想要封装内部函数,但为了测试的目的,匿名点击处理程序也可以暴露在范围内:

element = angular.element('<bar-foo');
expect(angular.element._data(element[0]).events.click).toContain(scope.onClick);

好吧,没有必要测试on方法。您可以在triggerHandler() 的帮助下测试事件绑定

link: function (scope, element) {
    element.on('click', 'something to heppen');
}

测试:

element = angular.element('<bar-foo></bar-foo>');
$compile(element)(scope); 
$(element[0]).triggerHandler('click');
expect('something binded to click event to happen');

如果您在beforeEach中编译了元素,如下所示:

myEl = '<div my-el>MY EL</div>';
scope = $rootScope.$new();
directiveElement = $compile(myEl)(scope);
scope.$digest();

尝试将mousedown替换为您正在测试的事件,如下所示:

expect(directiveElement.on.mousedown).toBeDefined;