測試angular中的controller

angularjs中的controller主要負責業務邏輯的處理、數據模型,頁面元素的展示等,通常一個controller會依賴一個或者多個service,通過service從數據庫拉數據後保存到controller,controller的簡陋的例子如下:

app.controller('EventController',['$scope','EventService',function($scope,EventService){     EventService.getEvents().then(function(events){ 
        $scope.events=events; 
        }); 
}]);

實際項目中的Service可能是這個樣子的:

app.factory('EventService', ['$http', '$q',
  function($http, $q) {
      return {
          getEvents: function() {
              var deferred = $q.defer();

              $http.get('/events.json').success(function(result) {
                  deferred.resolve(result);
              }).error(function(result) {
                  deferred.reject(result);
              });

              return deferred.promise;
          }
      };
  }]);

通常是返回一個Promise,當數據都加載完成後執行controller中的then方法,關於Promise的更多討論,有興趣的可以戳 http://hcc0926.blog.51cto.com/172833/1614576 http://hcc0926.blog.51cto.com/172833/1614586 http://hcc0926.blog.51cto.com/172833/1554745


測試依賴service的controller

 通常來講,在單元級別的測試中,我們不希望Service真正的發送請求,只是需要一個模擬的service,這個service只存在於我們要測試的controller中。我們先看一個例子:

var app = angular.module('MyApp');

describe("EventController", function() {
  var scope, q;
  var controllerFactory;
  var mockSerivce = {};
  var events = ["event1", "event2", "event3"];
  
 //注入controller所需要的angular服務,
  beforeEach(function() {
      module("MyApp");
      inject(function($rootScope, $controller, $q) {
          controllerFactory = $controller;
          scope = $rootScope.$new();
          q = $q;
      });
  });

//mock一個service,通過jasmine的createSpy方法創建一個替代方法,當調用service的相關方法時返//回這個替代方法,數據被包含到promise中,
  beforeEach(function() {
      var deferred = q.defer();
      deferred.resolve(events);
      mockSerivce.getEvents = jasmine.createSpy('getEvents');
      mockSerivce.getEvents.andReturn(deferred.promise);
  });

//通過這個方法實例化controller
  function initController() {
      return controllerFactory('EventController', {
          $scope: scope,
          EventService: mockSerivce
      });
  }

//每次測試controller都要實例化一次controller
  it("should have a events list", function() {
      initController();
      scope.$digest();
      expect(scope.events.length).toEqual(3);
      expect(scope.events).toEqual(events);
  });
});



參考:http://icodeit.org/2013/12/how-to-test-controller-in-angularjs/

   http://nathanleclaire.com/blog/2013/12/13/how-to-unit-test-controllers-in-angularjs-without-setting-your-hair-on-fire/


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章