2014-12-24 10 views
10

ich eine Funktion wie diese:Winkel Jasmin: ‚undefined‘ ist kein Objekt - Sendung innerhalb Timeout - Fehler

$scope.doIt = function(x, y) 
{ 
    $timeout(function() 
    { 
    $rootScope.$broadcast('xxx', 
    { 
     message: xxx, 
     status: xxx 
    }); 
    }); 
} 

Diese Funktion funktioniert so weit in Ordnung. Aber während ich einen Test schrieb, hatte ich einige Probleme.

describe('test doIt function...', function() 
     { 
     var $rootScope, $timeout; 

     beforeEach(inject(function (_$rootScope_, _$timeout_) 
     { 
      $rootScope = _$rootScope_; 
      $timeout = _$timeout_; 
      spyOn($rootScope, '$broadcast'); 
      spyOn(scope, 'doIt').and.callThrough(); 
     })); 

     it('test broadcast will be called', inject(function() 
     { 
      var testObj = { 
      message: 'test1', 
      status: 'test2' 
      }; 

      scope.doIt('test1', 'test2'); 

      expect($rootScope.$broadcast).not.toHaveBeenCalledWith('xxx', testObj); 

      $timeout.flush(); 

      expect($rootScope.$broadcast).toHaveBeenCalledWith('xxx', testObj); 

     })); 
     } 
    ); 

Dies wird in dem folgenden Fehler am Ende:

TypeError: 'undefined' is not an object (evaluating '$rootScope.$broadcast('$locationChangeStart', newUrl, oldUrl, $location.$$state, oldState).defaultPrevented')

Warum? Was mache ich falsch? Ohne $ Timeout in Funktion und Test funktioniert es gut.

Vielen Dank im Voraus für Ihre Hilfe.

:)

Edit: Eine weitere Sendung dann dieses Problem erwartet wird, ausgegeben wird. hmm

+0

Rückkehr der Linie wird der Fehler zu zeigen? der vor dem Flush oder danach? – elaijuh

+0

Das scheint ein bisschen künstlich, also bin ich mir nicht sicher, was Sie wirklich versuchen zu bekommen. Ich nehme an, Sie definieren "Geltungsbereich" woanders in der Spezifikation (und $ Scope in dem zu testenden Code). Sie injizieren $ rootScope irgendwo in den Code-in-Test? Unabhängig davon scheint dies ein weniger als idealer Test zu sein: Anstatt $ rootScope. $ Broadcast auszuspionieren, sollten Sie nicht einfach auf die Übertragung in Ihrer Spezifikation auf die gleiche Art und Weise hören wie im normalen Code (dh $ scope). $ on) –

Antwort

1

Problem -

Angular Rahmen versucht $broadcast Funktion aufzurufen und ein Objekt aus dieser Funktion dafür zu erwarten, die defaultPrevented Eigenschaft.

Aber wegen

spyOn($rootScope, '$broadcast');

Anweisung in beforeEach blockieren die tatsächliche Umsetzung von $broadcast nicht geltend gemacht werden könnten und daher ist es nicht ein Objekt zurück, das defaultPrevented Eigenschaft enthält.

Lösung -

Bewegen Sie die spyOn($rootScope, '$broadcast'); Anweisung von beforeEach Block it Block genau vor scope.doIt('test1', 'test2');.

+4

Ich hatte das gleiche Problem und reparierte es, indem ich den Spion auf 'andCallThrough() einstellte' – Katana24

+0

@ Katana24 Sie retteten mir gerade viel Zeit, vielen Dank! – SupimpaAllTheWay

+0

+1 Das löste mein Problem. Ein separater Test warf seltsame Broadcast-Fehler. Spion in den es bewegend, hat es repariert. – Jeremy

8

Ich habe dieses Problem behoben von prevent

spyOn($rootScope, '$broadcast').and.returnValue({preventDefault: true}) 
Verwandte Themen