Attempting to conduct a test on an AngularJS custom directive using Karma + Jasmine has proven to be quite perplexing. After scouring various resources online, I came across a method that seems to work, but it doesn't feel like the right approach. Let's take a look at an example code snippet from 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, $compile, $injector) {
elm = angular.element("<test defined='defined'></test>");
scope = $rootScope;
scope.defined = false;
$compile(elm)(scope);
scope.$digest();
}));
it("should not be initially defined", function() {
expect(elm.scope().$$childTail.isDefined()).toBe(false);
});
});
Now let's examine the content of the directive template file test.html:
<button data-ng-click='defined = true'></button>
Lastly, here is the excerpt from 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
});
};
When running the tests using the command line:
karma start karma.conf.js
I noticed something unusual - the scope function defined in the controller can only be accessed via the $$childTail
attribute. Attempting to call it directly from the element's scope resulted in an undefined value elm.scope().isDefined()
. Is there a more efficient solution available?
Thank you!