Angular:如何监视$ element.on

时间:2015-11-16 15:29:53

标签: javascript angularjs unit-testing angularjs-directive jasmine

我有一个指令在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与我的spec文件中的元素不同。最有可能(未经验证)element[0]可能是相同的。我还试图窥探angular.element

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

但这似乎比修复更多(我还需要像isloateScope之类的函数)。

无论如何,是否有一些简单的方法可以监视指令中使用的元素的on函数?

3 个答案:

答案 0 :(得分:2)

链接功能可以单独测试

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

如果它足够简单(远离attrs,所需的控制器,依赖关系),否则规范将导致更多问题,而不是它可以解决。

否则,可以对其进行测试like it is done by the framework

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);

答案 1 :(得分:1)

嗯,没有必要测试var array = ["a", Object{ qty="1" }, "b", Object{ qty="1" }, "c", Object{ qty="2" } ]; var id = $(this).attr("id"); var qty = $('#item_'+id).val(); var index = $.inArray(id, array); if(index === -1){ array.push(id, {'qty' : qty}); }else{ array.splice(index, 1); } 方法。您可以在source code

的帮助下测试事件绑定
on

测试:

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

答案 2 :(得分:0)

如果你已经在这样的beforeEach中编译了你的元素:

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

尝试将mousedown替换为您正在测试的事件:

expect(directiveElement.on.mousedown).toBeDefined;