javascript - 测试 AngularJs + Jasmine 时无法获取指令中的元素

标签 javascript angularjs unit-testing angularjs-directive 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);

  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 单元测试代码:

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);
    });

  });
});

此外,在 Plunker 上重现问题花了很长时间,但它仍然在 jasmine-html 上抛出 TypeError: createElement is not a function

最佳答案

好吧,我在这里找到了答案 Jasmine unit testing an element is not :hidden 。我之前尝试过向文档添加指令元素,但没有成功。我唯一错过的是注入(inject) $document 来测试范围。如果没有它,document 对象将不可用。

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]);
    });

  });
});

更新了plunker http://plnkr.co/edit/JPOBm7?p=preview

关于javascript - 测试 AngularJs + Jasmine 时无法获取指令中的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32525123/

相关文章:

unit-testing - 使用 NUnit 测试项目列表

javascript - 为什么我的函数在调用较长时间后会失败?

javascript - 如何使用相同的 key 将多个对象添加到本地存储

javascript - 在 Angular js中使用推送功能

c++ - 在 Visual Studio 中执行单个 Boost Test 单元测试

c# - FluentAssertions : int. Should().Equals 返回错误结果?

javascript - 使用 UglifyJS Mangle 公共(public)变量名称

javascript - Zapier 返回带有空字段的对象数组 - 需要添加空字符串

angularjs - 如何从 Amazon 上的 Angular 应用程序 (Elastic Beanstalk) 中的 url 中删除 #

angularjs - Angular.JS 触发两个异步服务调用,然后在两者都完成后执行操作