测试 AngularJs + Jasmine 时无法在指令中获取元素 [英] Can not get element in directive while testing AngularJs + Jasmine

查看:23
本文介绍了测试 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆