测试自定义角度指令是否显示/隐藏元素

时间:2015-04-23 18:47:05

标签: javascript jquery html css angularjs

我有一个自定义指令,它根据另一个服务的值显示/隐藏一个元素。我尝试创建一个测试,看看该指令是否做了应该做的事情。一开始我再次测试了":可见"选择器,但即使我知道元素实际显示,它总是返回false。

it('Should show element if logged', function () {
    element = angular.element('<p hc-auth>Some Text</p>');
    AuthService.Logged = true;
    scope = $rootScope.$new();
    scope.$apply(function () {
        $compile(element)(scope);
    });
    expect(element.is(":visible")).toBeTruthy();
});

经过一些调试后,我意识到在测试执行期间,即使显示器设置为阻塞,元素的宽度和高度也为0,因此&#34;:可见&#34;选择器总是返回false。我改变它来检查显示选择器,现在它正确地测试元素,但这似乎太依赖于如何显示元素的实现。

it('Should show element if logged', function () {
    element = angular.element('<p hc-auth>Some Text</p>');
    AuthService.Logged = true;
    scope = $rootScope.$new();
    scope.$apply(function () {
        $compile(element)(scope);
    });
    expect(element.css('display')).toBe('block');
});

这种情况的最佳方法是什么?

2 个答案:

答案 0 :(得分:6)

你的问题让我想知道角度测试ngHidengShow如何,这是他们的spec文件中的一个片段:

it('should show if the expression is a function with a no arguments', function() {
  element = jqLite('<div ng-show="exp"></div>');
  element = $compile(element)($scope);
  $scope.exp = function() {};
  $scope.$digest();
  expect(element).toBeShown();
});

似乎很整洁。起初我以为他们必须使用jquery-jasmine,它会公开toBeHidden匹配器(虽然结果不是toBeShown),事实上他们自己写custom matcher来确定能见度:

// [jtrussell] Custom Jasmine Matcher
toBeShown: function() {
  this.message = valueFn(
      "Expected element " + (this.isNot ? "" : "not ") + "to have 'ng-hide' class");
  return !isNgElementHidden(this.actual);
}

// [jtrussell] ...

// [jtrussell] The helper from elsewhere in same file
function isNgElementHidden(element) {
  // we need to check element.getAttribute for SVG nodes
  var hidden = true;
  forEach(angular.element(element), function(element) {
    if ((' '  + (element.getAttribute('class') || '') + ' ').indexOf(' ng-hide ') === -1) {
      hidden = false;
    }
  });
  return hidden;
}

所以我猜他们有点作弊......检查是否存在.ng-hide类以确定可见性。但我想他们曾经在你的鞋子里,并认为这是最好的路线,因为角度已经支持这个类名。

由于我们已经使用了角度,您可以考虑使用.ng-hide类来设置可见性并编写类似的帮助。

修改

作为一个方面说明我&#39;会说,添加/删除.ng-hide设置可见性将免费获得您的模块的用户已经到位,该类任何ngAnimations的利益<。 / p>

答案 1 :(得分:1)

由于可见的元素是一个加载的术语而:visible不是真正的CSS选择器,所以没有银弹。

以下是一些可能性

  1. 在Jasmine中使用not

    期望(element.css( '显示器'))not.toBe( '隐藏');

  2. 然而,这不会涵盖元素显示但不可见的情况,因为它没有不透明度或者它位于另一个元素后面。

    1. 获取元素的getBoundingClientRect()。然后检查每个角落的document.elementFromPoint是否未返回您希望隐藏的元素。