AngularJs的超时单元测试



我有一个带有以下代码片段的angular指令,我该如何对其进行单元测试?

 link: function($scope, iElm) {
            $(iElm).on('paste', function(){
                $timeout(function(){
                        $scope.lastScan = Date.now();
                    });
                }); 
            }

您需要使用$timeout.flush(),它将立即调用您定义的任何$timeout回调,因此它实质上使其成为用于测试目的的同步代码。

试试这个:

演示

app.js

app.directive('myDirective', function($timeout){
  return function($scope, iElm) {
    // no need to use jQuery
    iElm.bind('paste', function(){
      console.log('**paste**')
      $timeout(function(){
        console.log('timeout')
        $scope.lastScan = Date.now();
      });
    }); 
    // $(iElm).on('paste', function(){
    //   $timeout(function(){
    //           $scope.lastScan = Date.now();
    //       });
    //   }); 
  }
});

appSpec.js

describe("My directive", function() {
    var element,
        $timeout, $compile, $scope;

    // load the module that has your directive
    beforeEach(module('plunker'));
    beforeEach(inject(function(_$timeout_, _$compile_, _$rootScope_) {
        $timeout = _$timeout_;
        $compile = _$compile_;
        $scope   = _$rootScope_.$new();
    }));
    function compileElement(){
        // use $compile service to create an instance of the directive
        // that we can test against
        element = $compile('<my-directive></my-directive>')($scope);
        // manually update scope
        $scope.$digest(); 
    }

    it("defines a 'lastScan' property", function() {
        compileElement();
        // trigger paste event
        element.triggerHandler('paste');
        // angular doesn't know about paste event so need
        // to manually update scope
        $scope.$digest();
        // immediately call $timeout callback
        // thus removing any asynchronous awkwardness
        $timeout.flush();
        // assert that directive has added property to the scope
        expect($scope.lastScan).toBeDefined();
    });
});

最新更新