6

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 runcode 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?

1
  • note: you defined var scope again inside of beforeEach. also: _ $rootScope vs _ $rootScope _ Commented Jun 5, 2013 at 9:58

3 Answers 3

3

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', ...]);
Sign up to request clarification or add additional context in comments.

Comments

2

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() {
    ...
    });
});

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.