我如何使用 jasmine 测试具有嵌套超时的 javascript 函数

how do i test javascript function with nested timeouts using jasmine

我有以下功能,可以简单地清除模糊输入。我正在使用 angular 材料,并且正在创建一个指令,以便在需要时添加。

   function clearTextOnBlurLink(scope, element, attrs, controller) {   
            $timeout(function() {
                var input = element.find('input'); 
                input.on('blur', function(e){
                    setTimeout(function(){
                        input.val('');              
                        input.triggerHandler('input'); 
                    }, 100);                
                });
            },0);
        }

我想测试它,但我无法让它工作。

这是我的测试:

    beforeEach(inject(function(_$rootScope_, _$compile_, _$timeout_) {

                $scope = _$rootScope_.$new();
                $compile = _$compile_;
                $timeout = _$timeout_;        
                $scope.searchText = 'blah';

                element = angular.element('\
                    <div mx-clear-on-blur> <input ng-model="searchText1"> </div>\
                ');

               element = $compile(element)($scope);
               $scope.$apply();
               $timeout.flush();       
      }));
 it('clears text on blur', function() {
        var input = element.find('input').eq(0);

        expect(input.val()).toBe('blah');
        expect($scope.searchText).toBe('blah');

        input1.triggerHandler('blur');

        expect(input.val()).toBe('');
        expect($scope.searchText).toBe('');


    });

好的,我开始将 setTimeout 更改为 $timeout。 如果没有 2 个超时,是否有更简单的方法?

您第二次使用 setTimeout 有什么原因吗?为什么不再次使用 $timeout...?另外 $timeout 通常有点代码味道,所以嵌套 $timeouts 感觉有点不对劲。 :p

无论如何,我想你的测试要通过,你需要在模糊后的测试中 $timeout.flush()

您也可以在测试中使用 setTimeout:

input1.triggerHandler('blur');
setTimeout(function() {
    expect(input.val()).toBe('');
    expect($scope.searchText).toBe('');
}, 100);

Jasmine 应该也有一个 waitsFor 方法:

input1.triggerHandler('blur');
waitsFor(function() { 
    return false; 
}, 100);
expect(input.val()).toBe('');
expect($scope.searchText).toBe('');