Reputation: 130
How can I unit test my directive?
What I have is
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>'
};
})
In my unit test I want to start with a very simple test
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);
});
});
This doesn't work though as the directive is registered on the app module and I don't want to include the module as that will make all of my config
and run
code run. That would defeat the purpose of testing the directive as a separate unit.
Am I supposed to put all my directives in a separate module and load just that? Or is there any other clever way of solving this?
Upvotes: 6
Views: 5116
Reputation: 15579
EDIT: I see the question has changed since my last answer.
You need to put your directive in an independant module.
For example:
angular.module('MyModule.directives');
To test only that module you may load that module explicitly in the test like this:
beforeEach(module('MyModule.directives'));
This will load that module and all its dependancies.
Remember to state the directive module as a dependancy in your MyModule definition in your app:
angular.module('MyModule', ['MyModule.directives', ...]);
Upvotes: 3
Reputation: 685
You should declare all your directives in 'youapp.directives' module and include that module in your directive tests.
In your app.js
angular.module('myApp', ['myApp.controllers', 'myApp.directives', 'myApp.services', 'myApp.filters']).config(...)
In your directives.js
angular.module('myApp.directives', []) .directive(.....)
Finally your directivesSpec.js
describe('directives specs', function() {
beforeEach(module('myApp.directives'));
describe('range', function() {
...
});
});
Upvotes: 2
Reputation: 1
The angular-seed project https://github.com/angular/angular-seed seems to have the opinion that directives should go in their own module that is then a dependency of the base app module.
So the directives go in a module called "myApp.directives" :
angular.module('myApp.directives', []).
directive('appVersion', ['version', function(version) {
return function(scope, elm, attrs) {
elm.text(version);
};
}]);
And then the base app module add the directive module as a 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'});
}]);
So then their test example just depends on the directive module
describe('directives', function() {
beforeEach(module('myApp.directives'));
etc...
I haven't actually tried this with your or my code yet but it looks like you were mostly looking for most common practice guidance.
Upvotes: 0