1

Внутри directive шахты наречено data-type-ahead я следующий в серии событий:AngularJS Test Unit element.bind

$scope.test = 5; 

// Bind blur event and clear the value of 
element.bind('blur', function(){ 
    $scope.test = 0; 
}); 

Я попытался множество вещей, чтобы использовать в модульном тесте, чтобы правильно проверьте функциональность этого события blur, однако я не был успешным. Я видел упоминание функции triggerHandler. Вот моя попытка модульного тестирования:

//Inject $compile and $rootScope before each test. 
beforeEach(inject(function(_$compile_, _$rootScope_) { 
    $compile = _$compile_; 
    $rootScope = _$rootScope_; 

    $scope = $rootScope.$new(); 
    $scope.test = 5 

    html = angular.element('<input type="text" data-type-ahead/>'); 

    //Apply $scope to directive html. 
    directive = $compile(html)($scope); 

    //Trigger digest cycle. 
    $scope.$digest(); 
})); 

it('should trigger the events bound to the blur event on the directive', function() { 
    html.triggerHandler('blur') 
    expect($scope.test).toEqual(0); 
}); 

Однако это не удается, потому что $scope.test пребывает на 5. Является ли это HTML-элемент является неправильным, мне нужен другой $digest или $apply для после того, как я вызвать событие?

ответ

2

У вас есть 2 способа заставить это работать. Первый добавляет тайм-аут, чтобы ваш метод (docs):

// somewhere above add - 
var originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL; 
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; 

// in your beforeEach 

beforeEach(function(){ 
html.triggerHandler('blur'); 
    setTimeout(function(){ 
    done(); 
}, 1000); 
}); 

it('should trigger the events bound to the blur event on the directive', 
    function() { 
    expect($scope.test).toEqual(0); 
    } 
); 

Я считаю, что это «хуже» практика (плохо или хуже, слишком отрицательное слово для тестирования - в тот момент, вы проверяете, вы уже лучше :)). В общем, я стараюсь избегать тестирования async, потому что в конечном итоге мои методы (узлы a.k.a.) синхронизируются внутри.

«лучшая практика» было бы написать метод, который изменяет значение так:

// in the directive's ctrl 
this.changeValue = function changeValue{ 
    $scope.test = 0; 
} 

// later on set the watcher 
// Bind blur event and clear the value of 
$element.bind('blur', this.changeValue); 

А затем проверить сам метод вместо тестирования асинхронной. Вы можете проверить $ element.bind (через spyOn (element, 'bind')), если вам нравится видеть, что ваши методы ctrl/link создают привязку.