2013-03-25 263 views
6

我該如何測試我的指令?單元測試AngularJS指令

我有什麼是

angular.module('MyModule'). 
    directive('range', function() { 
     return { 
      restrict: 'E', 
      replace: true, 
      scope: { 
       bindLow: '=', 
       bindHigh: '=', 
       min: '@', 
       max: '@' 
      }, 
     template: '<div><select ng-options="n for n in [min, max] | range" ng-model="bindLow"></select><select ng-options="n for n in [min, max] | range" ng-model="bindHigh"></select></div>' 
    }; 
}) 

在我的單元測試我想從一個非常簡單的測試

describe('Range control', function() { 
    var elm, scope; 

    beforeEach(inject(function(_$compile_, _$rootScope) { 
     elm = angular.element('<range min="1" max="20" bind-low="low" bind-high="high"></range>'); 

     var scope = _$rootScope_; 
     scope.low = 1; 
     scope.high = 20; 
     _$compile_(elm)(scope); 
     scope.$digest(); 
    })); 

    it('should render two select elements', function() { 
     var selects = elm.find('select'); 

     expect(selects.length).toBe(2); 
    }); 
}); 

這不工作,雖然作爲該指令被註冊的應用模塊並且我不想包含該模塊,因爲這會使我的所有代碼都運行configrun。這將把作爲單獨單位測試指令的目的打敗。

我應該把我所有的指令放在一個單獨的模塊中,並加載?或者有沒有其他解決這個問題的巧妙方法?

+0

記:你beforeEach內再次定義變種範圍。另外:_ $ rootScope vs _ $ rootScope _ – felix 2013-06-05 09:58:23

回答

3

編輯:自從我上次回答以來,我看到問題發生了變化。

你需要把你的指令放在一個獨立的模塊中。

例如:

angular.module('MyModule.directives'); 

爲了僅測試模塊,你可以明確地加載模塊,在這樣的測試:

beforeEach(module('MyModule.directives')); 

這將加載模塊及其所有依賴關係。

記住陳述指令模塊作爲扶養在MyModule中定義您的應用程序:

angular.module('MyModule', ['MyModule.directives', ...]); 
0

角度種子項目 https://github.com/angular/angular-seed 似乎也認爲,指示應在自己走模塊,然後是基本應用程序模塊的依賴項。

於是指示去一個叫模塊「myApp.directives」:

angular.module('myApp.directives', []). 
    directive('appVersion', ['version', function(version) { 
    return function(scope, elm, attrs) { 
     elm.text(version); 
    }; 
    }]); 

然後是基礎應用模塊添加指令模塊作爲depenency

// Declare app level module which depends on filters, and services 
angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives']). 
    config(['$routeProvider', function($routeProvider) { 
    $routeProvider.when('/view1', {templateUrl: 'partials/partial1.html', controller: MyCtrl1}); 
    $routeProvider.when('/view2', {templateUrl: 'partials/partial2.html', controller: MyCtrl2}); 
    $routeProvider.otherwise({redirectTo: '/view1'}); 
    }]); 

那麼接下來他們的測試實例只取決於指令模塊

describe('directives', function() { 
    beforeEach(module('myApp.directives')); 
etc... 

我實際上沒有嘗試過這與你或我的c但是,它看起來像你主要是尋找最常見的實踐指導。

2

您應該在'youapp.directives'模塊中聲明所有的指令,並在指令測試中包含該模塊。

在你app.js

angular.module('myApp', ['myApp.controllers', 'myApp.directives', 'myApp.services', 'myApp.filters']).config(...) 

在你的指令。JS

angular.module('myApp.directives', []) .directive(.....) 

最後你directivesSpec.js

describe('directives specs', function() { 
    beforeEach(module('myApp.directives')); 

    describe('range', function() { 
    ... 
    }); 
});