【问题标题】:AngularJS: Directive restrict : 'E' prevents element click() event being called in Jasmine unit testAngularJS:指令限制:'E' 防止在 Jasmine 单元测试中调用元素 click() 事件
【发布时间】:2013-12-18 23:02:32
【问题描述】:

这里有几个指令和单元测试。

这是第一个指令:

directive('myTestDirective', function() {
    return {
        link: function(scope, element, attrs) {
            element.on("click", function(e) {
            scope.clicked = true;
            console.log("clicked");
        }
    }
});

还有单元测试:

describe('my test directive', function() {
    beforeEach(function() {
        .....
        inject($compile, $rootScope) {
            scope = $rootScope.$new();
            html = '<div my-test-directive></div>';
            elem = angular.element(html);
            compiled = $compile(elem);
            compiled(scope);
            scope.$digest();
        }
    });
    it('should set clicked to true when click() is called', function() {
        elem[0].click();
        expect(scope.clicked).toBe(true);
    });
});

当上述单元测试运行时,测试通过,clicked 被记录到控制台。

但是,请考虑添加了 restrict: E 的此指令:

directive('myDirective', function() {
    return {
        restrict: 'E',
        link: function(scope, element, attrs) {
            element.on("click", function(e) {
            scope.clicked = true;
            console.log("clicked");
        }
    }
});

还有单元测试:

describe('my directive', function() {
    beforeEach(function() {
        .....
        inject($compile, $rootScope) {
            scope = $rootScope.$new();
            html = '<my-directive></my-directive>';
            elem = angular.element(html);
            compiled = $compile(elem);
            compiled(scope);
            scope.$digest();
        }
    });
    it('should set clicked to true when click() is called', function() {
        elem[0].click();
        expect(scope.clicked).toBe(true);
    });
});

此测试失败。 clicked 未记录到控制台。从调试中我可以看到为指令绑定click() 绑定的函数没有被执行。

如何继续使用restrict : 'E',同时仍保留在单元测试中模拟点击的能力?

更新:感谢 Michal 的 plunkr,我已经成功了。

我将 inject() 函数更改为:

inject(function($compile, $rootScope, $document) {
    scope = $rootScope.$new();
    html = '<my-test-directive-element></my-test-directive-element>';
    elem = angular.element(html);
    $compile(elem)(scope);
    scope.$digest();
});

在此之后,使用限制属性点击和限制元素都可以工作。

Plukr 在这里: http://plnkr.co/edit/fgcKrYUEyCJAyqc4jj7P

【问题讨论】:

  • 如果您添加一个简单的template = '&lt;div&gt;&lt;/div&gt;,您会看到不同的行为吗?
  • 尝试将注入方法内容改为:scope = $rootScope.$new(); html = '&lt;my-directive&gt;&lt;/my-directive&gt;'; compiled = $compile(html)(scope); scope.$digest();
  • 我创建了a Plunkr,其指令和测试与您的示例非常相似。通过模拟点击,这两项测试都顺利通过。你能发布一个显示你的测试失败的 Plunkr 吗?
  • 我尝试了 David 和 tschiela 的两个建议,结果仍然相同。
  • 问题中的链接 plunkr 目前显示正确的行为。

标签: javascript unit-testing angularjs jasmine


【解决方案1】:

使用 jqLit​​e on('click') 不是很 Angular-ish,我认为它不会被 Angular 摘要循环处理(因此,您在该回调中添加到您的范围内的任何内容都不会在您的DOM,除非您手动执行)。您应该更喜欢在您的指令中使用内置的 ng-click 指令,因此 html 代码变为:

<my-directive ng-click="onClick()"></my-directive>

和你的指令:

directive('myDirective', function() {
  return {
    restrict: 'E',
    link: function(scope, element, attrs) {
      scope.onClick = function() {
        scope.clicked = true;
        console.log("clicked");
      }
    }
  }
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-15
    • 1970-01-01
    • 2015-07-29
    • 2013-08-29
    • 1970-01-01
    • 2015-01-18
    相关资源
    最近更新 更多