angularjs - 如何为 keydown 绑定(bind)指令编写单元测试?

标签 angularjs unit-testing angularjs-directive

这是我需要进行单元测试的代码。

todomvc.directive('todoEscape', function () {
    var ESCAPE_KEY = 27;
    return function (scope, elem, attrs) {
        elem.bind('keydown', **function (event) {
            if (event.keyCode === ESCAPE_KEY) {
                scope.$apply(attrs.todoEscape);**
            }
        });

        scope.$on('$destroy', function () {
            elem.unbind('keydown');
        });
    };
});

但是上面带**的部分始终没有被覆盖。覆盖率报告显示

语句:75%,分支:0,函数:75%,行:75%

以下是我的测试代码

'use strict';
beforeEach(module('todomvc'));

describe('todoEscape directive', function () {
  var scope, compile;

  beforeEach(inject(function ($rootScope, $compile) {
      scope = $rootScope.$new();
      compile = $compile;
  }));

  beforeEach(function() {
      var elem = angular.element('<input todo-escape="escape">');
      compile(elem)(scope);
      spyOn(element, 'bind').and.returnValue('keydown');
      var event = document.createEvent("Events");
      event.initEvent('keydown');
      event.keyCode = 27;
      element.triggerHandler(event);
  });

  it('should call callback function when the event happens', function() {
      expect(scope.escape()).toHaveBeenCalled();
  });

  it('deregisters on scope $destroy', function() {
      scope.$destroy();
      expect(scope.escape()).not.toHaveBeenCalled();
  });
});

我对 AngularJS 和单元测试非常陌生。请帮忙。

最佳答案

为了提供更高的覆盖率,您的测试应该是这样的。

describe('todoEscape directive', function () {
  var scope, compile, element;

  beforeEach(inject(function ($rootScope, $compile) {
      scope = $rootScope.$new();
      scope.escapeCallback = jasmine.createSpy('escapeCallback');
      compile = $compile;
  }));

  beforeEach(function() {
      var elem = angular.element('<input todo-escape="escapeCallback">');
      element = compile(elem)(scope);
  });

  it('should call callback function on escape', function() {
    // given
    var givenEvent = { keyCode: 27 };

    // when
    element.triggerHandler('keydown', givenEvent);
    scope.$digest();

    // then
    expect(scope.escapeCallback).toHaveBeenCalled();
  });

  it('should not call escape callback when other key is down', function () {
    // given
    var givenEvent = { keyCode: 123 };
    scope.$digest();

    // when
    element.triggerHandler('keydown', givenEvent);

    // then
    expect(scope.escapeCallback).not.toHaveBeenCalled();
  });

  it('should unbind keydown event when scope is destroyed', function() {
    // given
    spyOn(element, 'unbind');

    // when
    scope.$destroy();

    // then
    expect(element.unbind).toHaveBeenCalledWith('keydown');
  });
});

如果您有任何疑问,请给我留言,我会尽力向您解释。

关于angularjs - 如何为 keydown 绑定(bind)指令编写单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32668751/

相关文章:

angular - 使用 stub 测试 Angular 服务

angularjs - AngularJS删除属性

events - 从 angularjs 指令触发点击事件

angularjs - 参数数量未知的 Angular 指令函数

angularjs - 在 Angular 限制增加后向表中添加更多行

angularjs - 防止 AngularJS 路由中的 url 编码

javascript - 将对象添加到 Firebase 时设置自己的 key - AngularFire

html - 如何在 ionic 中为 Android 设备新打开的窗口添加关闭按钮?

c# - 单元测试错误 : This function can only be invoked from LINQ to Entities

java - Spring 3.2 : Unit testing of @Scope ("request") no longer works