测试一个操纵DOM的angularjs指令

时间:2013-06-24 09:27:01

标签: jquery angularjs angularjs-directive karma-runner

我是Karma的初学者,如果这是一个愚蠢的问题,请原谅我。

我正在测试我的一个方面,这是两种特殊的方式:

1 - 它根据范围内容有条件地更改模板,并重新编译链接器

中的指令元素
var linker = function(scope, element, attrs) {
//...

var getTemplate = function(contentType) {
            var template = '';

            switch(contentType) {
            case 'canvas':
                template = '<div> stuff here </div>';
                break;
            case 'div':
                template = '<div> other stuff here </div>';
                break;
                //...
             }

            return template;
        };

var html = getTemplate(scope.content.uiType);
            var ae = angular.element(html);

            element.replaceWith(ae);
            $compile(ae)(scope);

}

2 - 它在链接器中使用jsplumb来记录指令元素并设置一些jsplumb端点:

// Inside the linker function

var outEndPoint = jsPlumb.addEndpoint (ae, { /* parameters */ }, AudioOutPoint);

调用jsPlumb.addEndpoint时会出现问题。调试库,似乎在某一点上,jsPlumb使用jQuery返回某个元素 - 它创建的元素 - 按照$(“#jsplumb-element”)的行;

jQuery依次执行tis行:

elem = document.getElementById( match[2] );

和getElementById返回null(可能是因为没有真正的DOM?)。此时,会引发异常,一切都崩溃了。

要明确:如果我为此语句设置断点,并在控制台中执行document.getElementsByTagName('div');,它将返回null

我正在使用Chrome来测试此指令,而简单的测试代码就是这样:

describe('Directive: hyPluginWindow', function () {

    beforeEach(module('hyacinthHostApp'));

    var element, $compile, scope;

    beforeEach(inject(function(_$compile_, $rootScope) {
        $compile = _$compile_;
        scope = $rootScope.$new();
    }));


  it('should set the right audioDestinations', inject(function () {

      scope.content = {
          name: "testElement",
          id: "testElement000",
          uiType: "canvas",
          audioIn: 0,
          audioOut: 1,
          audioSources: [],
          audioDestinations: []
      };

      var grandparent = angular.element('<div id="pluginArea"></div>');
      var parent =  angular.element('<div class="plugin"></div>');
      var element = angular.element('<div hy-plugin-window content="content"></div>');
      grandparent.append(parent);
      parent.append(element);
      debugger;
      element = $compile(element)(scope);

      expect(scope.audioDestinations.length).toBe(1);

  }));
});

期望部分永远不会被满足,因为该指令在链接后立即排除。 请注意,在应用程序中,此代码工作正常(因此问题出在测试指令中)。

我错过了什么?

1 个答案:

答案 0 :(得分:7)

将元素附加到DOM,在测试中,执行以下操作:

grandparent.appendTo(document.body);

顺便说一下。您使用的插件不应该document.getElementsByTagName('div')而是element.find(...)。然后,您不必将其附加到DOM,这将使测试运行得更快。