角度单位测试链接功能中的$ attrs

时间:2016-03-16 23:29:49

标签: javascript jquery angularjs unit-testing

我已经为具有控制器的指令设置了一些测试。设置

并不困难
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<div class="row">
  <div class="col-md-12">
    <div class="support-box">
      <h3>Start a Live Chat with one of our Tech Team</h3>
      <button class="btn btn-info btn-lg" id="tech-support" type="button">
        <h3>Start</h3>
        <img src="http://www.nestlearning.com/img/design/icon-live-chat.png" id="support-image" class="img-responsive" />
      </button>
    </div>

但是,我对链接功能有点困惑。示例不是来自应用程序的代码,但类似。

        var html = angular.element("<div explore></div>");
        $rootScope = $rootScope.$new();
        element = $compile(html)($rootScope);
        $rootScope.$digest(element);

        controller = element.scope();

如果我嘲笑 $ rootScope 有没有办法访问$ attr?我没看到

var exploreLink = function($scope, $el, $attr) {
   $scope.gallery = [];

    $scope.secondarytitle = $attrs.title;
}



return {
    restrict: 'A',
    scope: true,
    link: ExploreLinks,
    templateUrl: 'LinkHtml'
    controller: LinkController
};
在$ rootScope上。

似乎我仍然会调用$ digest,因为它是指令的一部分。我假设有必要编译类似于上面列出的步骤的指令。

1 个答案:

答案 0 :(得分:2)

link是单元测试的一个可怕的地方,其内容应该留给E2E测试,或者整个指令应该被视为黑盒子,其结果必须与范围对象匹配。

如果它包含应与Protractor一起测试的DOM相关逻辑,那就没关系。并且如果链接函数包含应该属于控制器的东西是不行的,根据公式'控制器将事物绑定到范围,链接将事物粘合在一起'。

每个注册的指令都以*Directive名称的Angular服务提供,其中部分可以进行测试或模拟。 link函数隐藏在DDO对象中compile函数内部的事实不会使任务更容易或更清晰。

测试链接功能可能与

一样令人毛骨悚然
  inject(function ($compile, $rootScope, exploreDirective) {
    ...
    var linkFn;
    var _compileFn = exploreDirective[0].compile;
    var _attrs;

    spyOn(exploreDirective[0], 'compile').and.callFake(function () {
      var _linkFn = _compileFn.apply(exploreDirective[0], arguments);

      var linkFn = jasmine.createSpy('linkFn');
      linkFn.and.callFake(function (scope, element, attrs, ctrls, transcludeFn) {
        // now attrs can be mocked or matched
        _attrs = attrs;
        return _linkFn(function (scope, element, attrs, ctrls, transcludeFn);
      }

      return linkFn;
    });

    $compile('<explore attr="...">')(scope);
    expect(linkFn).toHaveBeenCalled();
    expect(_attrs.attr).toBe('...');

始终在指令控制器中使用$attrs本地依赖关系,以支持attrs link中的this param进行测试。将attrs分配给控制器中的$scope$compile('<explore attr="...">')(scope)是正确的做法。

顺便说一句,内部Angular逻辑不应该被模拟或测试。可以安全地假设$attrs.attr === '...'将导致volumeControl.setValue(volumeControl.getMaximum()); removes illegalStateException at Server