角度单位在$ attr上测试$ watch

时间:2022-03-21 13:15:41

From my understanding $attr.$observe fires once. So there are times to use $watch on an attribute. I am looking to unit test a directive that requires ngModel

从我的理解$ attr。$观察火灾一次。所以有时候在属性上使用$ watch。我期待单元测试一个需要ngModel的指令

scope.$watch(attr.ngModel, function (newValue) {
            minlength = parseInt(attr.minLength);
            scope.minLengthValidator(newValue);
        });

Since this is using scope in the Link function it seems like I could call $digest.

由于这是在Link函数中使用范围,所以我似乎可以调用$ digest。

My mocked attribute starts like so...

我的模拟属性就这样开始......

html = angular.element("<input ng-model=\"myUnit\" min-length=\"3\">");

I am not sure if I can just redefine element.attr('min-length') inside of my spec and run a $digest or if there is a more complex approach since the the watch is passing a new value.

我不确定我是否可以在我的规范中重新定义element.attr('min-length')并运行$ digest,或者如果有更复杂的方法,因为watch会传递一个新值。

the rest of my mock set up is like so

我的模拟设置的其余部分是这样的

 $rootScope = $rootScope.$new();
 element = $compile(html)($rootScope);
 $rootScope.$digest(element);

 controller = element.controller('ngModel');
 scope = element.scope();

I have not tested a $watch on a attribute before so any direction that points me towards solving this would be much appreciated.

我之前没有对某个属性进行过$ watch的测试,所以任何指向我解决这个问题的方向都会非常感激。

1 个解决方案

#1


2  

scope.$watch(attr.ngModel, ...) will create a watcher on myUnit scope property. Once the watcher is created, it isn't bound to ngModel attribute value.

范围。$ watch(attr.ngModel,...)将在myUnit范围属性上创建一个观察者。创建观察程序后,它不会绑定到ngModel属性值。

It can be tested as any other scope watcher:

它可以像任何其他范围观察者一样进行测试:

scope.myUnit = ...;
$rootScope.$digest();
expect(scope.minLengthValidator).toHaveBeenCalledWith(...);

From my understanding $attr.$observe fires once.

从我的理解$ attr。$观察火灾一次。

No, $attrs.$observe observer will fire on each attribute change, it is preferable to $scope.$watch. As the manual states,

不,$ attrs。$ observe观察者将触发每个属性更改,它最好是$ scope。$ watch。如手册所述,

Use $observe to observe the value changes of attributes that contain interpolation (e.g. src="{{bar}}"). Not only is this very efficient but it's also the only way to easily get the actual value because during the linking phase the interpolation hasn't been evaluated yet and so the value is at this time set to undefined.

使用$ observe来观察包含插值的属性的值更改(例如src =“{{bar}}”)。这不仅非常有效,而且它也是轻松获得实际值的唯一方法,因为在链接阶段,插值尚未进行评估,因此此时的值设置为未定义。

The problem is that attributes belong to DOM and can't be tested cleanly. For controller specs $attrs local dependency can be mocked, but it isn't possible in directive specs. For testability reasons it is preferable to bind attributes to scope properties and test the scope only with no $attrs involved.

问题是属性属于DOM,无法进行干净的测试。对于控制器规格,$ attrs可以模拟局部依赖,但在指令规范中是不可能的。出于可测试性原因,最好将属性绑定到范围属性,并仅在不涉及$ attrs的情况下测试范围。

#1


2  

scope.$watch(attr.ngModel, ...) will create a watcher on myUnit scope property. Once the watcher is created, it isn't bound to ngModel attribute value.

范围。$ watch(attr.ngModel,...)将在myUnit范围属性上创建一个观察者。创建观察程序后,它不会绑定到ngModel属性值。

It can be tested as any other scope watcher:

它可以像任何其他范围观察者一样进行测试:

scope.myUnit = ...;
$rootScope.$digest();
expect(scope.minLengthValidator).toHaveBeenCalledWith(...);

From my understanding $attr.$observe fires once.

从我的理解$ attr。$观察火灾一次。

No, $attrs.$observe observer will fire on each attribute change, it is preferable to $scope.$watch. As the manual states,

不,$ attrs。$ observe观察者将触发每个属性更改,它最好是$ scope。$ watch。如手册所述,

Use $observe to observe the value changes of attributes that contain interpolation (e.g. src="{{bar}}"). Not only is this very efficient but it's also the only way to easily get the actual value because during the linking phase the interpolation hasn't been evaluated yet and so the value is at this time set to undefined.

使用$ observe来观察包含插值的属性的值更改(例如src =“{{bar}}”)。这不仅非常有效,而且它也是轻松获得实际值的唯一方法,因为在链接阶段,插值尚未进行评估,因此此时的值设置为未定义。

The problem is that attributes belong to DOM and can't be tested cleanly. For controller specs $attrs local dependency can be mocked, but it isn't possible in directive specs. For testability reasons it is preferable to bind attributes to scope properties and test the scope only with no $attrs involved.

问题是属性属于DOM,无法进行干净的测试。对于控制器规格,$ attrs可以模拟局部依赖,但在指令规范中是不可能的。出于可测试性原因,最好将属性绑定到范围属性,并仅在不涉及$ attrs的情况下测试范围。