2013-04-03 143 views
5

我剛剛開始角度,我想爲我的控制器寫一些簡單的單元測試,這裏是我得到的。angularjs - 測試控制器

app.js:

'use strict'; 


// Declare app level module which depends on filters, and services 
angular.module('Prototype', ['setsAndCollectionsService']). 
    config(['$routeProvider', function($routeProvider) { 
    $routeProvider.when('/dashboard', {templateUrl: 'partials/dashboard.html', controller: 'DashboardController'}); 
    $routeProvider.when('/setsAndCollections', {templateUrl: 'partials/setsAndCollections.html', controller: SetsAndCollectionsController}); 
    $routeProvider.when('/repetition', {templateUrl: 'partials/repetition.html', controller: RepetitionController}); 
    $routeProvider.otherwise({redirectTo: '/dashboard'}); 
    }]); 

和controllers.js

'use strict'; 

/* Controllers */ 

    var myApp = angular.module('Prototype'); 

    myApp.controller('DashboardController', ['$scope', function (scope) { 
     scope.repeats = 6; 
    }]); 

/*function DashboardController($scope) { 
$scope.repeats = 5; 
};*/ 

function SetsAndCollectionsController($scope, $location, collectionsService, repetitionService) { 
    $scope.id = 3; 
    $scope.collections = collectionsService.getCollections(); 
    $scope.selectedCollection; 
    $scope.repetitionService = repetitionService; 

    $scope.switchCollection = function (collection) { 
     $scope.selectedCollection = collection; 
    }; 

    $scope.addCollection = function() { 
     $scope.collections.push({ 
      name: "collection" + $scope.id, 
      sets: [] 
     }); 
     ++($scope.id); 
    }; 

    $scope.addSet = function() { 
     $scope.selectedCollection.sets.push({ 
      name: "set" + $scope.id, 
      questions: [] 
     }); 
     ++($scope.id); 
    }; 

    $scope.modifyRepetition = function (set) { 
     if (set.isSelected) { 
      $scope.repetitionService.removeSet(set); 
     } else { 
      $scope.repetitionService.addSet(set); 
     } 

     set.isSelected = !set.isSelected; 
    }; 

    $scope.selectAllSets = function() { 
     var selectedCollectionSets = $scope.selectedCollection.sets; 

     for (var set in selectedCollectionSets) { 
      if (selectedCollectionSets[set].isSelected == false) { 
       $scope.repetitionService.addSet(set); 
      } 
      selectedCollectionSets[set].isSelected = true; 
     } 
    }; 

    $scope.deselectAllSets = function() { 
     var selectedCollectionSets = $scope.selectedCollection.sets; 

     for (var set in selectedCollectionSets) { 
      if (selectedCollectionSets[set].isSelected) { 
       $scope.repetitionService.removeSet(set); 
      } 
      selectedCollectionSets[set].isSelected = false; 
     } 
    }; 

    $scope.startRepetition = function() { 
     $location.path("/repetition"); 
    }; 
} 

function RepetitionController($scope, $location, repetitionService) { 
    $scope.sets = repetitionService.getSets(); 
    $scope.questionsLeft = $scope.sets.length; 
    $scope.questionsAnswered = 0; 
    $scope.percentageLeft = ($scope.questionsLeft == 0 ? 100 : 0); 

    $scope.endRepetition = function() { 
     $location.path("/setsAndCollections"); 
    }; 
} 

現在我在轉換全局函數控制器通過角API定義變量的過程中,你可以通過舉例的DashboardController見。

現在,在我的測試:

describe("DashboardController", function() { 
    var ctrl, scope; 

    beforeEach(inject(function ($rootScope, $controller) { 
     scope = $rootScope.$new(); 
     ctrl = $controller('DashboardController', {$scope: scope}); 
    })); 

    it("has repeats attribute set to 5", function() { 
     expect(scope.repeats).toBe(5); 
    }); 
}); 

我越來越

Error: Argument 'DashboardController' is not a function, got undefined 

我想知道的話,哪裏是我的錯?如果我理解這個權利,ctrl = $controller('DashboardController', {$scope: scope});應該將我新創建的示波器注入我的DashboardController,以便使用屬性填充它 - 在本例中爲repeats

+0

您是否確定將您的controllers.js包含在您的測試運行器中?例如在你的karma-runner配置文件中? – Xesued 2013-04-03 23:22:57

+0

我檢查過,文件讀取OK,有趣的是,如果我取消註釋'DashboardController'的全局函數樣式,這個簡單的測試通過,所以這個文件應該包括在內。 – Andna 2013-04-03 23:30:34

+3

因爲它值得你不應該掛在你的$ scope變量的元素。 $範圍應該包含對您的模型的參考,但它不是您的模型。例如'$ scope.id'應該是'$ scope.SetsAndCollectionsModel.id'。其原因來自於試圖將主要類型從子範圍設置爲父範圍的問題。你可以觀看描述這個[這裏](http://www.egghead.io/video/DTx23w4z6Kc)的視頻。創建Angular的Misko在[最佳實踐](http://www.youtube.com/watch?v=ZhfUv0spHCY)視頻中對此進行了討論(抱歉,沒有直接鏈接到時間) – 2013-05-18 14:08:02

回答

19

您需要先設置您的Prototype模塊。

beforeEach(module('Prototype')); 

添加到您的測試,當前beforeEach將工作。

describe("DashboardController", function() { 
    var ctrl, scope; 

    beforeEach(module('Prototype')); 

    beforeEach(inject(function ($rootScope, $controller) { 
    scope = $rootScope.$new(); 
    ctrl = $controller('DashboardController', {$scope: scope}); 
    })); 

    it("has repeats attribute set to 5", function() { 
    expect(scope.repeats).toBe(5); 
    }); 
}); 
+0

謝謝,那是失蹤的片段。 – Andna 2013-04-04 07:47:45