I'm testing an angular directive (i.e. top-level-element) which includes other directive via ng-include. And I want to test that my directive includes any template passed to ng-include and directives inside this template are compiled, run and so on. I understand that this is kind of testing the angular itself, but top-level-element is partly rendered not by the angular but with _.template due to performance reasons. So I want to be sure that ng-include isn't broken by this custom rendered part.
Currently I create new directive in my module, but this pollutes the module. I'd like to either create a mock directive or at least have an ability to unregister the directive I create in test. Does anybody has any ideas on how to do it?
Roughly the test looks like following:
describe('top level directive', function() {
var mockDirective;
var mockDirectiveName;
var $templateCache;
var $compile;
var $scope;
var element;
beforeEach(function() {
mockDirectiveName = 'includedDirective';
mockDirective = {
restrict: 'E',
controller: jasmine.createSpy('mockDirective.controller'),
template: '<p>some markup</p>',
link: jasmine.createSpy('mockDirective.link')
};
var topLevelDirectiveModule = angular.module('topLevelDirectiveModule');
// checking whether mockDirective has already been defined to avoid double definition
var isTopLevelDirectiveDefined = topLevelDirectiveModule._invokeQueue.some(function(item) {
return item[2][0] === mockDirectiveName;
});
if (!isTopLevelDirectiveDefined) {
/** I don't like polluting real module with test directive, but I couldn't find any way to register mock directive
or unregister this one after tests */
topLevelDirectiveModule.directive(mockDirectiveName, function() {
return mockDirective;
});
}
inject(function($injector) {
$compile = $injector.get('$compile');
$scope = $injector.get('$rootScope').$new();
$templateCache = $injector.get('$templateCache');
});
$templateCache.put('some/included.html', '<included-directive></included-directive>');
element = $compile('<top-level-directive></top-level-directive>')($scope);
$scope.$digest();
});
it('should show html', function() {
expect(element.html()).toContain(mockDirective.template);
});
it('should run directive\'s controller', function() {
expect(mockDirective.controller).toHaveBeenCalled();
});
it('should run directive\'s link', function() {
expect(mockDirective.link).toHaveBeenCalled();
});
});
And directive:
angular.module('topLevelDirectiveModule').directive('topLevelDirective', function() {
return {
template: '<div class="contents_of_this_are_rendered_by_lodash"></div>' +
'<ng-include src="some/included.html"></ng-include>',
restrict: 'E',
controller: function() { /* some real controller to be here */},
link: funciton($scope, elem, attrs, controllers) {
var tpl = _.template('some template');
elem.find('.contents_of_this_are_rendered_by_lodash').html(tpl());
}
};
});
Aucun commentaire:
Enregistrer un commentaire