I'm trying to test an AngularJS custom directive with Karma + Jasmine. I found a way to do it checking many references around the web. But the solution doesn't appear to be the correct way. Let's first check an example, this is the test.js:
angular.module("app", [])
.directive("test", function() {
return {
restrict: 'E',
scope: {
defined: '='
},
templateFile: "test.html",
controller: function($scope) {
$scope.isDefined = function() {
return $scope.defined;
};
}
};
});
describe("Test directive", function() {
var elm, scope;
beforeEach(module("app"));
beforeEach(module("test.html"));
beforeEach(inject(function($rootScope, $pile, $injector) {
elm = angular.element("<test defined='defined'></test>");
scope = $rootScope;
scope.defined = false;
$pile(elm)(scope);
scope.$digest();
}));
it("should not be initially defined", function() {
expect(elm.scope().$$childTail.isDefined()).toBe(false);
});
});
Now the directive template file test.html:
<button data-ng-click='defined = true'></button>
And finally the karma.conf.js:
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['jasmine'],
files: [
'angular.min.js',
'angular-mocks.js',
'test.js',
'test.html'
],
exclude: [],
preprocessors: {
"test.html": ['ng-html2js']
},
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Firefox'],
singleRun: true
});
};
I was running the tests with the following mand line:
karma start karma.conf.js
What appears to be really strange to me is that the scope function defined in the controller can only be accessed by the $$childTail
attribute. If I try to call it directly from the element's scope I got an undefined value elm.scope().isDefined()
. Does someone has a better solution for this?
Thanks!
I'm trying to test an AngularJS custom directive with Karma + Jasmine. I found a way to do it checking many references around the web. But the solution doesn't appear to be the correct way. Let's first check an example, this is the test.js:
angular.module("app", [])
.directive("test", function() {
return {
restrict: 'E',
scope: {
defined: '='
},
templateFile: "test.html",
controller: function($scope) {
$scope.isDefined = function() {
return $scope.defined;
};
}
};
});
describe("Test directive", function() {
var elm, scope;
beforeEach(module("app"));
beforeEach(module("test.html"));
beforeEach(inject(function($rootScope, $pile, $injector) {
elm = angular.element("<test defined='defined'></test>");
scope = $rootScope;
scope.defined = false;
$pile(elm)(scope);
scope.$digest();
}));
it("should not be initially defined", function() {
expect(elm.scope().$$childTail.isDefined()).toBe(false);
});
});
Now the directive template file test.html:
<button data-ng-click='defined = true'></button>
And finally the karma.conf.js:
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['jasmine'],
files: [
'angular.min.js',
'angular-mocks.js',
'test.js',
'test.html'
],
exclude: [],
preprocessors: {
"test.html": ['ng-html2js']
},
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Firefox'],
singleRun: true
});
};
I was running the tests with the following mand line:
karma start karma.conf.js
What appears to be really strange to me is that the scope function defined in the controller can only be accessed by the $$childTail
attribute. If I try to call it directly from the element's scope I got an undefined value elm.scope().isDefined()
. Does someone has a better solution for this?
Thanks!
Share Improve this question edited Mar 30, 2014 at 10:43 Sergio 28.8k11 gold badges90 silver badges132 bronze badges asked Mar 24, 2014 at 13:30 faersonsfaersons 6152 gold badges8 silver badges19 bronze badges1 Answer
Reset to default 6Because your directive uses an isolated scope, instead of
elm.scope()
you should be able to use
elm.isolateScope()
The function isolateScope
is explained (briefly) at http://docs.angularjs/api/ng/function/angular.element