2014-01-13 3 views
9

У меня есть следующий тест:Дразнящего объект события в единичном событии тестирования AngularJS

it('Should keep location when user rejects confirmation', inject(function ($controller, $rootScope) { 
     var confirmStub = sinon.stub(), 
      eventStub = { 
       preventDefault: sinon.spy() 
      }; 

     miscServiceStub = function() { 
      this.confirm = confirmStub; 
     }; 

     confirmStub.returns(false); 

     initializeController($controller, 'Builder', $rootScope); 

     $rs.$broadcast('$locationChangeStart', eventStub); 
     expect(confirmStub).toHaveBeenCalledOnce(); 
     expect(confirmStub).toHaveBeenCalledWith('Are you sure you want to leave? you will loose any unsaved changes.'); 
     expect(eventStub.stopPropagation).toHaveBeenCalledOnce(); 

     miscServiceStub = function() {}; 
    })); 

который проверяет этот код:.

$rootScope.$on('$locationChangeStart', function (event) { 
    dump(arguments); 
    if (!$miscUtils.confirm('Are you sure you want to leave? you will loose any unsaved changes.')){ 
     event.preventDefault(); 
    } 
}); 

событие $ stopPropagation не называют фиктивное события, и дамп (аргументы) показывает, что оно передается в событие сразу после реального объекта события:

Chromium 31.0.1650 (Ubuntu) DUMP: Object{ 
    0: Object{name: '$locationChangeStart', targetScope: Scope{$id: ..., $$childTail: ..., $$childHead: ..., $$prevSibling: ..., $$nextSibling: ..., $$watchers: ..., $parent: ..., $$phase: ..., $root: ..., this: ..., $$destroyed: ..., $$asyncQueue: ..., $$postDigestQueue: ..., $$listeners: ..., $$isolateBindings: ..., activeTab: ..., routeParams: ...}, preventDefault: function() { ... }, defaultPrevented: false, currentScope: Scope{$id: ..., $$childTail: ..., $$childHead: ..., $$prevSibling: ..., $$nextSibling: ..., $$watchers: ..., $parent: ..., $$phase: ..., $root: ..., this: ..., $$destroyed: ..., $$asyncQueue: ..., $$postDigestQueue: ..., $$listeners: ..., $$isolateBindings: ..., activeTab: ..., routeParams: ...}}, 
    1: Object{stopPropagation: spy} 
} 

, как я могу сделать это поэтому объект события является событием mock, а не самим объектом реального события? Правильно ли я подхожу к этому? Я совершенно новый для Angular, и любые комментарии к коду/тесту были бы весьма признательны.

Если вам нужен более связанный код, пожалуйста, сообщите мне.

ответ

3

В этой строке:

$rs.$broadcast('$locationChangeStart', eventStub); 

вы предоставить аргумент, который будет transmittet наряду с этим событием, а не само событие. Вот почему вы попадете сюда:

$rootScope.$on('$locationChangeStart', function (event) 

2 объекта в качестве аргументов. Полная подпись для Вашего мероприятия должно быть:

$rootScope.$on('$locationChangeStart', function (event, eventStub) 

Итак, вы не можете проверить вызов stopPropagation в том, как вы пытались его.

Если вы посмотрите на угловой src (строка 12185 ...), вы увидите, что событие создано без какой-либо возможности издеваться над этим объектом. И сам масштаб $ не издевается угловато-макет.

Если кто-то хочет проверить, что вызвано preventDefault, я бы написал службу, которая имеет функцию, которая вызывает preventDefault. Эту услугу можно легко заглянуть.

36

$scope.$broadcast возвращает Event объект, так что вы можете сделать это:

var event = $scope.$broadcast("someEvent"); 
expect(event.defaultPrevented).toBeTruthy(); 
Смежные вопросы