Unit-testing directive controllers in Angular without making controller global

I prefer at times to include my controller along with the directive so I need a way to test that.

First the directive

angular.module('myApp', [])
  .directive('myDirective', function() {
    return {
      restrict: 'EA',
      scope: {},
      controller: function ($scope) {
        $scope.isInitialized = true
      },
      template: '<div>{{isInitialized}}</div>'
    }
})

Then the tests:

describe("myDirective", function() {
  var el, scope, controller;

  beforeEach inject(function($compile, $rootScope) {
    # Instantiate directive.
    # gotacha: Controller and link functions will execute.
    el = angular.element("<my-directive></my-directive>")
    $compile(el)($rootScope.$new())
    $rootScope.$digest()

    # Grab controller instance
    controller = el.controller("myDirective")

    # Grab scope. Depends on type of scope.
    # See angular.element documentation.
    scope = el.isolateScope() || el.scope()
  })

  it("should do something to the scope", function() {
    expect(scope.isInitialized).toBeDefined()
  })
})

See angular.element documentation for more ways to get data from an instantiated directive.

Beware that instantiating the directive implies that the controller and all link functions will already have run, so that might affect your tests.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)