测试 AngularJs + Jasmine 时无法在指令中获取元素 [英] Can not get element in directive while testing AngularJs + Jasmine
问题描述
我有一个带有外部模板的 angularjs 指令.它运行良好,但我无法为它编写 jasmine 单元测试.这是 plunker 复制代码:http://plnkr.co/edit/JPOBm7?p=preview一个>
我所有的尝试都在同一问题上失败.链接方法在运行单元测试时在获取模板的 DOM 元素时崩溃.它说:TypeError: canvas is null in http://run.plnkr.co/YHHxxmSgCiQxjrjw/app.js (line 8)
我不知道如何使它工作.请帮忙.
我的简化指令代码:
angular.module('app', []).directive('canvasDirective', canvasDirective);函数画布指令(){var 链接 = 函数 () {var canvas = document.getElementById('canvas'),context = canvas.getContext('2d'),testText = '测试一下!';画布宽度 = 200;画布高度 = 200;context.fillStyle = '#cccccc';context.fillRect(0, 0, canvas.width, canvas.height);context.font = 'bold 32px Arial';context.textAlign = '中心';context.fillStyle = '白色';context.fillText(testText, 100, 100);context.strokeText(testText, 100, 100);}返回 {限制:'A',链接:链接,模板网址:'canvas.html'}}
Jasmine 单元测试代码:
describe('带画布的测试指令', function() {var $compile, $scope, $templateCache, defaultData, validTemplate,html = '',createDirective = 函数(数据,模板){榆树;$scope.data = 数据 ||默认数据;elm = $compile(template || validTemplate)($scope);$scope.$digest();回归榆树;}beforeEach(module('app'));beforeEach(注入(函数(_$compile_,_$rootScope_,_$templateCache_){$compile = _$compile_;$scope = _$rootScope_.$new();$templateCache = _$templateCache_;var template = $templateCache.put('canvas.html', html);}));描述('创建时',函数(){it('应该呈现预期的输出', function () {var element = createDirective(null, html);期望(元素.查找('画布').长度).toBe(1);});});});
此外,在Plunker上重现问题需要很长时间,但它仍然在jasmine-html
上抛出TypeError: createElement is not a function
.
好吧,我在这里找到了答案Jasmine 单元测试元素不是 :hidden.我之前曾尝试向文档添加指令元素,但没有奏效.我唯一错过的是注入 $document
来测试范围.document
对象没有它就无法使用.
describe('带画布的测试指令', function() {var $compile, $scope, $templateCache, $document, 模板,html = '',canvasHtml = '<div class="canvas-wrapper"><canvas id="canvas"></canvas></div>';beforeEach(module('app'));beforeEach(注入(函数(_$compile_,_$rootScope_,_$templateCache_,_$document_){$document = _$document_;$compile = _$compile_;$scope = _$rootScope_.$new();$templateCache = _$templateCache_;template = $templateCache.put('canvas.html', canvasHtml);}));var createDirective = 函数 () {var elm = angular.element(html);$compile(elm)($scope);document.body.appendChild(elm[0]);$scope.$digest();回归榆树;};描述('创建时',函数(){it('应该呈现预期的输出', function () {var element = createDirective();期望(元素.查找('画布').长度).toBe(1);document.body.removeChild(element[0]);});});});
更新的 plunker http://plnkr.co/edit/JPOBm7?p=preview一个>
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
.
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
这篇关于测试 AngularJs + Jasmine 时无法在指令中获取元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!