2016-12-04 91 views
1

我創建了一個服務,即存儲回調函數。當角度調整大小和/或方向改變事件發生時,存儲的回調將被調用。處理回調函數的茉莉花測試服務

我想寫一些測試在茉莉花這項服務。 有一個addCallback方法。這個存儲回調函數。我創建了這個測試用例,但我不知道如何檢查'print2'函數被調用。

describe('Testing Resize-updater service',function(){ 

var resizeUpdater; 
var $window; 
beforeEach(module('app.services')); 
beforeEach(inject(function(_resizeUpdater_,_$window_){ 
    resizeUpdater = _resizeUpdater_; 
    $window = _$window_; 
})); 

describe('Add a Callback and resize event',function(){ 

    var change; 

    it('Test 1',inject(function(){ 
     var $timeout = _$timeout_; 

     $window.innerWidth = 1368; 
     $window.innerHeight = 768; 
     function print2(){ 
      change = "called" 
     } 
     resizeUpdater.addCallback(print2); 
     $window.innerWidth = 1300;  //this trigger resize event 
     expect(change).toBe("called"); 

    })); 
}); 
}); 

這裏是全程服務代碼:

(function() { 
'use strict'; 

angular 
    .module('app.services') 
    .factory('resizeUpdater', ['$window','$q','$timeout','$log',UpdaterService ]); 

function UpdaterService($window, $q, $timeout, $log){ 

var api = {}; 

var size = { 
    width: undefined, 
    height: undefined, 
    orientation: undefined 
}; 


api.getSize = function(){ 
    size.width = $window.innerWidth; 
    size.height = $window.innerHeight; 
    size.orientation = (function(){ 
     if (size.width >= size.height){ 
      return "landscape"; 
     } else { 
      return "portrait"; 
     } 
    })(); 
    return size; 
}; 

api.list = []; 

api.addCallback = function(callback) { 
    api.list.push(callback); 
}; 

api.removeCallback = function(callback){ 
    var index = api.list.indexOf(callback); 
    delete api.list[index]; 
}; 

/*private method*/ 
var runAll = function() { 

    for(var item in api.list){ 
     var obj = new Obj(api.list[item]); 
     obj.execute(); 
    } 

}; 

function Obj(callback) { 
    this.promise = undefined; 
    this.callback = callback; 
    this.execute = function() { 
     var defer = $q.defer(); 
     this.callback(function (response) { 
      if (response === 'error') { 
       defer.reject('Error occured.'); 
       $log.error('Failed - '+ callback.name + ' - ' + (new Date).toString()); 
      } else { 
       defer.resolve(response); 
      } 
     }); 

     this.promise = defer.promise; 
     this.promise.then(function(result){ 
      $log.log('Executed - '+ callback.name + ' - ' + (new Date).toString()); 
     }); 
    }; 
} 

angular.element($window).on('resize',(function(){ 
    var timer_promise; 
    return function(){ 
     if (timer_promise) { 
      $timeout.cancel(timer_promise); 
     } 
     timer_promise = $timeout(function(){ 
      runAll(); 
     }, 500); 
    }; 

})()); 

return api; 

}})(); 

回答

0

好你的測試看起來不錯,但你應該manualy觸發resize事件,然後運行消化週期:

$window.innerWidth = 1000; 
angular.element($window).triggerHandler('resize'); 
$scope.$digest(); 
$timeout.flush(); 

和更好地使用茉莉花間諜:

var spy = jasmine.createSpy('spy'); 
resizeUpdater.addCallback(spy); 
// .... code 
expect(spy).toHaveBeenCalled(); 
+0

,如何處理asynchron電話嗎?因爲觸發事件需要一點時間來解決承諾,這是在調用回調之前創建的。 –

+0

我ahve更新了我的答案,您應該執行異步超時加入 $ timeout.flush(); – letsanov

+0

謝謝。但$ scope。$ digest是重要的嗎?因爲我沒有創建控制器實例。是否需要測試服務? –

0

您可以使用sinon

var print2 = sinon.spy(); 
resizeUpdater.addCallback(print2); 
$window.innerWidth = 1300; 
expect(print2.called).toBe(true); 
+0

這個解決方案看起來不錯,但這個時候,我不想增加額外的庫 –