In our app we have several layers of nested directives. I\'m trying to write some unit tests for the top level directives. I\'ve mocked in stuff that the directive itself ne
The clean way of mocking a directive is with $compileProvider
beforeEach(module('plunker', function($compileProvider){
$compileProvider.directive('d1', function(){
var def = {
priority: 100,
terminal: true,
restrict:'EAC',
template:'this is a mock',
};
return def;
});
}));
You have to make sure the mock gets a higher priority then the directive you are mocking and that the mock is terminal so that the original directive will not be compiled.
priority: 100,
terminal: true,
The result would look like the following:
Given this directive:
var app = angular.module('plunker', []);
app.directive('d1', function(){
var def = {
restrict: 'E',
template:' d1 '
}
return def;
});
You can mock it like this:
describe('testing with a mock', function() {
var $scope = null;
var el = null;
beforeEach(module('plunker', function($compileProvider){
$compileProvider.directive('d1', function(){
var def = {
priority: 9999,
terminal: true,
restrict:'EAC',
template:'this is a mock',
};
return def;
});
}));
beforeEach(inject(function($rootScope, $compile) {
$scope = $rootScope.$new();
el = $compile(' ')($scope);
}));
it('should contain mocked element', function() {
expect(el.find('.mock').length).toBe(1);
});
});
A few more things:
When you create your mock, you have to consider whether or not you need replace:true
and/or a template
. For instance if you mock ng-src
to prevent calls to the backend, then you don't want replace:true
and you don't want to specify a template
. But if you mock something visual, you might want to.
If you set priority above 100, your mocks's attributes will not be interpolated. See $compile source code. For instance if you mock ng-src
and set priority:101
, then you'll end-up with ng-src="{{variable}}"
not ng-src="interpolated-value"
on your mock.
Here is a plunker with everything. Thanks to @trodrigues for pointing me in the right direction.
Here is some doc that explains more, check the "Configuration Blocks" section. Thanks to @ebelanger!