user3111277
user3111277

Reputation: 2297

Unit Test Directive Controllers in AngularJS

I'm trying to fully understand how to test directives in AngularJS with Jasmine. Currently, I have a directive that is setup as shown here:

.directive('myDirective', function() {
    return {
        restrict: 'E',
        transclude: true,
        replace: true,
        scope: {
          title:'=',
          state:'@'
        },
        templateUrl: 'myHtml.tpl.html',
        controller: function ($scope) {
          // Business Logic Specific to the Directive goes in here
        }
    };
})

As the code snippet above shows, my directive has a controller inside the directive definition. The specific directive I'm trying to test is fairly complicated. The controller in the directive has over 200 lines of code. I'm trying to figure out how to write unit tests around the contents of the this controller. Currently I have the following:

describe('myApp', function () {
    var $scope;

    beforeEach(module('myApp'));
    beforeEach(inject(function ($controller, $rootScope) {
        $scope = $rootScope.$new();
    }));

    it('should create my directive', inject(function ($rootScope, $compile, $log) {
      var card = angular.element('<my-directive></my-directive>');
      $compile(card)($rootScope);
      $scope.$digest();

      expect($log.assertEmpty).not.toThrow();
    }));
});

The unit test above tests the creation of the directive itself. However, I can't figure out how to test the controller inside of the directive. Is there a way to do this? If so, how?

Thank you!

Upvotes: 3

Views: 2857

Answers (2)

Andre Sanguinetti
Andre Sanguinetti

Reputation: 91

You can test your controller using the following code:

describe('myApp', function () {
var $scope;

beforeEach(module('myApp'));
beforeEach(inject(function ($controller, $rootScope) {
    $scope = $rootScope.$new();
    var card = angular.element('<my-directive></my-directive>');
    $compile(card)($rootScope);
    $scope.$digest();
    controller = element.controller
}));

it('should create my directive', inject(function ($rootScope, $compile, $log) {
    //TRY YOUR BUSINESS LOGIC TESTS HERE
    //$scope.yourFunction(yourArgs...);
    //expect($scope.yourVars).toSomething
}));

});

Upvotes: 1

idursun
idursun

Reputation: 6335

As far as I remember there is a syntax for separating controller of a directive like:

.directive('myDirective', function() {
    return {
        restrict: 'E',
        transclude: true,
        replace: true,
        scope: {
          title:'=',
          state:'@'
        },
        templateUrl: 'myHtml.tpl.html',
        controller: 'MyDirectiveCtrl as ctrl'
    };
})

and registering it as a regular controller

.controller("MyDirectiveCtrl", function($scope) {})

So if you do this then you can create this controller by using $controller and test happily.

Upvotes: 4

Related Questions