Reputation: 298
I've got an angularjs directive with external template. It works well but I can not write jasmine unit tests for it. Here is plunker reproduced code: http://plnkr.co/edit/JPOBm7?p=preview
All my tries failed on the same issue. Link method crashes on getting template's DOM element while running unit-test. It says: TypeError: canvas is null in http://run.plnkr.co/YHHxxmSgCiQxjrjw/app.js (line 8)
I have no idea how to make it work. Help, please.
My simplified directive code:
angular.module('app', [])
.directive('canvasDirective', canvasDirective);
function canvasDirective () {
var link = function () {
var canvas = document.getElementById('canvas'),
context = canvas.getContext('2d'),
testText = 'Test it!';
canvas.width = 200;
canvas.height = 200;
context.fillStyle = '#cccccc';
context.fillRect(0, 0, canvas.width, canvas.height);
context.font = 'bold 32px Arial';
context.textAlign = 'center';
context.fillStyle = 'white';
context.fillText(testText, 100, 100);
context.strokeText(testText, 100, 100);
}
return {
restrict: 'A',
link: link,
templateUrl: 'canvas.html'
}
}
Jasmine unit-test code:
describe('Test directive with canvas', function() {
var $compile, $scope, $templateCache, defaultData, validTemplate,
html = '<div data-canvas-directive></div>',
createDirective = function (data, template) {
var elm;
$scope.data = data || defaultData;
elm = $compile(template || validTemplate)($scope);
$scope.$digest();
return elm;
}
beforeEach(module('app'));
beforeEach(inject(function(_$compile_, _$rootScope_, _$templateCache_){
$compile = _$compile_;
$scope = _$rootScope_.$new();
$templateCache = _$templateCache_;
var template = $templateCache.put('canvas.html', html);
}));
describe('when created', function () {
it('should render the expected output', function () {
var element = createDirective(null, html);
expect(element.find('canvas').length).toBe(1);
});
});
});
Besides, it took a very long time to reproduce issue on Plunker but it still throws TypeError: createElement is not a function
on jasmine-html
.
Upvotes: 2
Views: 6089
Reputation: 298
Well, I've found my answer here Jasmine unit testing an element is not :hidden. I've tried to add directive element to document before, but it didn't work. The only thing I've missed was to inject $document
to test scope. document
object is not available without it.
describe('Test directive with canvas', function() {
var $compile, $scope, $templateCache, $document, template,
html = '<div data-canvas-directive></div>',
canvasHtml = '<div class="canvas-wrapper"><canvas id="canvas"></canvas></div>';
beforeEach(module('app'));
beforeEach(inject(function(_$compile_, _$rootScope_, _$templateCache_, _$document_){
$document = _$document_;
$compile = _$compile_;
$scope = _$rootScope_.$new();
$templateCache = _$templateCache_;
template = $templateCache.put('canvas.html', canvasHtml);
}));
var createDirective = function () {
var elm = angular.element(html);
$compile(elm)($scope);
document.body.appendChild(elm[0]);
$scope.$digest();
return elm;
};
describe('when created', function () {
it('should render the expected output', function () {
var element = createDirective();
expect(element.find('canvas').length).toBe(1);
document.body.removeChild(element[0]);
});
});
});
Updated plunker http://plnkr.co/edit/JPOBm7?p=preview
Upvotes: 4