在测试期间更改单向绑定指令属性而不更新指令范围

时间:2014-08-07 19:34:18

标签: javascript angularjs testing jasmine directive

我正在尝试使用jasmine测试角度指令。

以下是受测试指令的简化示例:

angular.module('app', []).directive('testDirective', [
  function() {
    return {
      restrict:'A',
      scope: {
        myAttr: '@'
      },
      link: function(scope, element, attrs) {
        element.html(scope.myAttr);

        scope.$watch('myAttr', function(n, o) {
          if(n !== o) {
            element.html(n);
          }
        });
      }
    };
  }
]);

使用隔离范围,它将属性data-my-attr的值单向绑定到myAttr的范围值,然后观察myAttr的值以进行任何更改,此时它会更新显示的元素。

为了清晰起见,此代码再次进行了大量修改,因此请原谅极为人为的例子。

测试正在编译包含该指令的元素,验证元素的初始html是否设置正确(它是)然后更改属性的值并期望元素中的相应更改发生(它不是)。这是测试代码的简化版本。

it('fires myAttr watch', function() {
    var body = angular.element('body');
    var template = angular.element('<div id="testid" data-test-directive data-my-attr="initialValue"/>');

    body.append([template]);
    compile(template)(scope);
    scope.$digest();

    expect(angular.element('#testid').text()).toEqual('initialValue');

    template.attr('data-my-attr', 'newValue');

    scope.$digest();

    expect(angular.element('#testid').text()).toEqual('newValue');
  });

虽然此指令在生产中使用时按预期工作,但在测试中似乎更新属性的值不会导致相应的范围值更新,这导致手表永远不会触发。为什么范围上的值不会更新,为什么这只会在测试中发生?

这是一个展示问题http://plnkr.co/edit/MmS1X2zrPZyGSUIVUsDg?p=preview

的傻瓜

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

您需要在使用新文本更新元素的属性后编译元素。在你的情况下,你根本不需要scope.digest(因为你并没有真正用{{modelvalue}}绑定文本)。原因是您没有附加绑定变量,而是将计划文本分配给属性,因此您需要重新编译该元素。

所以你只需要这样做: -

template.attr('data-my-attr', 'newValue');
compile(template)(scope);

<强> Demo

如果您的测试是这样的(使用指令时使用角度绑定): -

var body = angular.element('body');
rootScope.initialValue ="initialValue";
var template = angular.element('<div id="testid" data-test-directive data-my-attr="{{initialValue}}"/>');

body.append([template]);
compile(template)(scope);
scope.$digest();
expect(angular.element('#testid').text()).toEqual('initialValue');

rootScope.initialValue = "newValue";
scope.$digest();

expect(angular.element('#testid').text()).toEqual('newValue');

它可以通过调用$ digest来实现。

<强> Demo