Reputation: 579
I am testing an AngularJS directive's controller.
describe('The directive', function() {
var element,
scope;
beforeEach(module('app'));
beforeEach(module('path/to/theDirective'));
beforeEach(inject(function($compile, $rootScope) {
element = angular.element('<div args="args" the-directive ></div>');
scope = $rootScope;
$compile(element)(scope);
scope.args = {
availableValues : [1, 2, 3],
key : 'id',
selectedValues : [],
searchText : '',
flag: false
};
scope.$digest();
}));
it('should compile', function() {
expect(element.html()).not.toBeNull();
});
describe('directive controller', function() {
var controller;
beforeEach(inject(function($controller) {
controller = element.controller('theDirective', {
$scope: scope
});
}));
it('should exist', function() {
expect(controller).not.toBeNull();
expect(controller).toBeDefined();
expect(scope.disableAddButton()).toBeDefined();
});
});
});
The first it
block passes, so the directive is compiling successfully. The second describe
block is not passing. The first two assertions in the second describe
's it
block pass, but the third one does not. It's returning TypeError: 'undefined' is not a function (evaluating 'scope.disableAddButton()')
. Is it possible that the controller is not being injected correctly, or is there more setup that needs to be done?
Upvotes: 1
Views: 921
Reputation: 579
It turns out that the scope needs to be isolated since the directive's controller is a private function.
Adding scope = element.isolateScope() || element.scope();
after scope.$digest();
does the trick. Also, moving the controller declaration to the first beforeEach
block isn't a bad idea.
The fixed test would look like this:
describe('The directive', function() {
var element,
scope,
theController;
beforeEach(module('app'));
beforeEach(module('path/to/theDirective'));
beforeEach(inject(function($compile, $rootScope) {
element = angular.element('<div args="args" the-directive ></div>');
scope = $rootScope;
$compile(element)(scope);
scope.args = {
availableValues : [1, 2, 3],
key : 'id',
selectedValues : [],
searchText : '',
flag: false
};
scope.$digest();
theController = element.controller('theDirective');
scope = element.isolateScope() || element.scope();
}));
it('should compile', function() {
expect(element.html()).not.toBeNull();
});
describe('directive controller', function() {
it('should exist', function() {
expect(theController).not.toBeNull();
expect(theController).toBeDefined();
expect(scope.disableAddButton()).toBeDefined();
});
});
});
Upvotes: 1