测试子超越指令与父指令的交互

Test child transcended directive interaction with parent directive

我想测试子指令和父指令之间的交互: 我的例子:

app.directive('foo', function() {
  return {
    restrict: 'AE',
    template: '<div><div ng-transclude></div></div>', 
    transclude: true,
    controller: function($scope) {
      this.add = function(x, y) {
        return x + y;
      }
  }
};
});

app.directive('bar', function() {
  return {
    restrict: 'AE',
    require: '^foo',
    template: '<div></div>', 
    replace: true,
    link: function(scope, element, attrs, foo) {

      console.log('link directive bar')
      scope.callFoo = function(x, y) {
        scope.sum = foo.add(x, y);
      }
    }
  };
});

我想测试 boo 和测试之间的交互,我不想模拟子指令 (boo) 这是我的测试:

it('ensures callFoo does whatever it is supposed to', function() {
  // Arrange
  var element = $compile('<div foo><bar></bar></div>')($scope);

  var ele = element.find('bar')
  var barScope = element.find('bar').scope();

  console.log('parent element :',element)
  console.log('child element :',ele)


  // Act Undefined :(
  barScope.callFoo(1, 2);

  // Assert
  expect(barScope.sum).toBe(3);
});

完整示例: http://plnkr.co/edit/vYNFwpkbbHi4lsgwJkA9?p=preview

您的指令已经编译,并且由于您在 bar 指令上有 replace: true,您将不再在 DOM 中找到 bar。您可以通过查看 element.html() 看到这一点,在您的情况下会显示类似这样的内容:

<div><div ng-transclude=""><div class="ng-scope"></div></div></div>

如果您删除 replace: true,您的测试就会成功。

否则,当jQuery没有加载时,jqLit​​e是有限的,它的find方法只能搜索标签名称。所以我试着像这样快速找到你的范围:

var barScope = element.find("div").eq(2).scope()

您的应用程序中是否加载了 jQuery?如果是这样,您也可以在测试中加载它,然后向 bar 元素添加更多信息,例如:

var element = $compile('<div foo><bar id="bar"></bar></div>')($scope);

然后你可以找到它:

var barScope = element.find('#bar').scope();