簡體   English   中英

Karma單元測試角度指令與關鍵事件處理程序

[英]Karma unit test angular directives with key event handler

幾個星期前,我進入了JavaScript的世界。 我使用Angular,然后用Karma和Jasmine測試我的代碼。 我有一個角度指令,我在測試時遇到了麻煩。

我有一個角度指令,意味着與<input>框一起使用。 該指令修改輸入框,因此它只接受數字作為輸入。 這是代碼的簡化版本:

var testDirective = angular.module('testDirectiveApp', []);

testDirective.directive('numberOnly', function() {
    return {
      restrict: 'A',
      link: function (scope, element) {
        element.on('keydown', function (event) {
          var k = event.keyCode;
          if (48 <= k && k <= 57) {
            return true;
          }
          event.preventDefault();
          return false;
        });
      }
    };
  });

我會在html中使用它,如下所示:

<div>
    Numbers only: <input number-only ng-required="true" 
                  ng-model="myNumber" type="text" maxlength="3" 
                  placeholder="NNN">
</div>

我想測試該指令是否正確連接,並成功過濾掉非數字輸入。 如果我輸入“a1b2c3”,輸入框應為“123”。

我已經嘗試了許多不同的方法將字符串輸入到輸入框並檢查一個值(輸入框,角度模型等),但是到目前為止它們都沒有。

以下測試是我的許多試驗的一個例子:

describe('numberOnly', function() {
  'use strict';
  var scope, element;

  beforeEach(module('testDirectiveApp'));

  beforeEach(inject(function($compile, $rootScope) {
    scope = $rootScope.$new();
    scope.testInput = "";
    element = angular.element('<input number-only ng-model="testInput" type="text">');
    $compile(element)(scope);
    scope.$digest();
  }));

  it('should accept number input', function() {

    triggerKeyDown(element, 49);

    expect(scope.testInput).toBe("1");
  });

  var triggerKeyDown = function (element, keyCode) {
    var e = $.Event("keydown");
    e.which = keyCode;
    e.keyCode = keyCode;

    $(element).trigger(e);
  };
});

我甚至嘗試編寫e2e測試來模擬用戶輸入。 我也嘗試從HTML元素中提取我的事件處理函數,並對函數進行單元測試。 到目前為止沒有工作。

我該如何最好地測試我的角度指令?

在測試中,您可以實際注入指令定義對象(DDO),然后直接調用鏈接函數,而無需實際創建元素。

Angular允許添加具有相同名稱但具有不同優先級的指令。 Angular以數組的形式創建指令的注入(因為有多個優先級事物)。 假設您只聲明了一次指令,我們可以假設您的DDO是數組中的第一個。

這段代碼未經測試,但應該可以幫助您完成大部分工作。

describe('numberOnly', function() {
  var scope, linkFunction;

  beforeEach(module('testDirectiveApp'));

  beforeEach(inject(function($compile, $rootScope, numberOnlyDirective) {
    scope = $rootScope.$new();
     //get the link function
     linkFunction = numberOnlyDirective[0].link;
   });

it('calls the event', function(){
    //make a mock element that has the 'on' function. 
    var onCallback;
    var mockElement = {
        on: function(eventName, cb){
          expect(eventName).toEqual("keydown");
           //save the callback so we can call it in our test
           onCallback = cb;
        }
    };

    linkFunction(scope, mockElement);
    var preventDefaultWasCalled = false;

    var mockEvent = {
        which: 1,
        keyCode: 1,
        preventDefault: function(){
           preventDefaultWasCalled = true;
        }
    };
    //trigger the 'keydown' event by calling the callback
    onCallback(mockEvent);
    expect(preventDefaultWasCalled).toEqual(true);
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM