2014-03-28 143 views
8

我得到這個錯誤,當我做如下測試:類型錯誤:無法讀取屬性「defaultPrevented」的未定義

it('should call pauseAnimationInterval if in focus', inject(function(SearchBoxData, intervalManager, $timeout){ 
    SearchBoxData.init_array = []; 
    SearchBoxData.inFocus = true; 
    SearchBoxData.init(intervalManager); 
    console.log(intervalManager.pauseTimeout); 
    console.log(intervalManager.pauseTimeoutTime); 
    console.log($timeout); 
    $timeout.flush(intervalManager.pauseTimeoutTime+1); 
    expect(rootScope.$broadcast).toHaveBeenCalledWith('onPauseInterval', intervalManager.loopIndex); 
})); 

它打破了上$timeout.flush(intervalManager.pauseTimeoutTime+1); 的$超時方法是所謂的intervalManager.pauseAnimationInterval()這裏面SearchBoxData.init(intervalManager)

intervalManager.pauseAnimationInterval = function(){ 

    intervalManager.safeCancel(intervalManager.continueInterval); 
    intervalManager.safeCancel(intervalManager.initInterval); 
    intervalManager.initInterval = null; 
    intervalManager.continueInterval = null; 

    intervalManager.pauseTimeout = $timeout(function() { 
    if(intervalManager.inFocus === true){ 
     intervalManager.loopIndex += 1; 
     if(intervalManager.loopIndex >= intervalManager.maxLoopIndex){ 
     intervalManager.loopIndex = 0; 
     } 
     $rootScope.$broadcast("onPauseInterval", intervalManager.loopIndex); 
     intervalManager.continueAnimationInterval(); 
    }else{ 
     // Important condition: retry after the timeout if no focus 
     // main reason of glitch 
     intervalManager.pauseAnimationInterval(); 
    } 
    }, intervalManager.pauseTimeoutTime); 

}; 

我之前沒有收到這個錯誤,我不確定我做錯了什麼。

更新:這裏是unminified版本angularJS的堆棧跟蹤:

at /Users/foo/projects/bar/vendor/assets/javascripts/angular.js:9268:88 
at Scope.$eval (/Users/foo/projects/bar/vendor/assets/javascripts/angular.js:11986:28) 
at Scope.$digest (/Users/foo/projects/bar/vendor/assets/javascripts/angular.js:11812:31) 
at Scope.$apply (/Users/foo/projects/bar/vendor/assets/javascripts/angular.js:12092:24) 
at Object.fn (/Users/foo/projects/bar/vendor/assets/javascripts/angular.js:13627:36) 
at Function.self.defer.flush (/Users/foo/projects/bar/spec/javascripts/lib/angular/angular-mocks.js:126:32) 
at Function.$delegate.flush (/Users/foo/projects/bar/spec/javascripts/lib/angular/angular-mocks.js:1689:20) 
at null.<anonymous> (/Users/foo/projects/bar/spec/javascripts/unit/services/searchboxdata_service_spec.js:71:16) 

更新2:我追查回SearchBoxData工廠的注入。我不確定它有什麼問題。無論何時創建$超時實例並使用flush方法,只需注入它都會導致錯誤。

更新3:我注意到這種情況,如果我注入或者$位置或依賴的一個途徑$(間接的,它與我到處使用一些基本的服務發生)。

更新4:這裏是重現它plunker!這是$廣播()「d $或發出()」 http://plnkr.co/edit/7XweXI?p=info

+0

比較遺憾的是答案,顯然沒有給予足夠的重視。稍後再看;) – bluehallu

+0

你有這樣的失敗測試的小提琴或蹲跳者嗎? – dmahapatro

+0

@dmahapatro我管理一個重現錯誤的重擊者。看我的編輯。 –

回答

25

範圍事件D是同步的,當他們完成了返回的事件對象。

在角有些事情取決於返回的事件對象,如ngRoute上。

所以你可以做什麼來解決這個問題,只需在你創建你的間諜時添加andCallThrough(),這樣它就可以調用原始函數併產生一個返回值。

另外,如果你不想使用真正的$廣播,你可以使用andCallFake()提供一個假的函數,可以返回任何你想要的。

例子:

beforeEach(function(){ 
    module('MyApp'); 
    inject(function($injector){ 
    rootScope = $injector.get('$rootScope'); 
    spyOn(rootScope,'$broadcast').andCallThrough(); // will prevent the reference error 
    }) 
}); 
+1

非常感謝@chronicsalsa,這個問題困擾了我好幾天。 –

+0

好的。如果沒有問題,我就不會那樣做。 :)據我們所知,一個很好的問題已經解決了一半。 ;) – dmahapatro

+8

注意,在茉莉花2.0及以上版本,語法是'and.callThrough();' –

相關問題