首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在AngularJS的指令测试中触发ng-change

如何在AngularJS的指令测试中触发ng-change
EN

Stack Overflow用户
提问于 2013-07-13 11:11:29
回答 5查看 36.9K关注 0票数 19

我有以下创建input元素的AngularJS指令。输入具有运行doIt()函数的ng-change属性。在我的指令的单元测试中,我想检查当用户更改输入时是否调用了doIt函数。但是测试没有通过。尽管它在浏览器中手动测试时可以正常工作。

指令:

代码语言:javascript
复制
...
template: "<input ng-model='myModel' ng-change='doIt()' type='text'>" 

测试:

代码语言:javascript
复制
el.find('input').trigger('change') // Dos not trigger ng-change

实时演示(ng-change):http://plnkr.co/edit/0yaUP6IQk7EIneRmphbW?p=preview

现在,如果我手动绑定change事件而不是使用ng-change属性,测试就会通过。

代码语言:javascript
复制
template: "<input ng-model='myModel' type='text'>",
link: function(scope, element, attrs) {
  element.bind('change', function(event) {
    scope.doIt();
  });
}

实时演示(手动绑定):http://plnkr.co/edit/dizuRaTFn4Ay1t41jL1K?p=preview

有没有一种方法可以使用ng-change并使其可测试?谢谢。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2013-07-14 14:17:23

从你的解释性评论中:

在指令的测试中,我想做的就是检查当用户更改输入时是否调用了

ng-change指示的表达式是否正确求值实际上是ngModel指令的责任,所以我不确定是否会以这种方式测试它;相反,我相信ngModelngChange指令已经正确地实现和测试,可以调用指定的函数,而只是测试调用函数本身是否会以正确的方式影响指令。可以使用端到端或集成测试来处理完全使用的场景。

也就是说,您可以获取驱动ngModel更改回调的ngModelController实例,并自己设置视图的值:

代码语言:javascript
复制
it('trigger doIt', function() {
  var ngModelController = el.find('input').controller('ngModel');
  ngModelController.$setViewValue('test');
  expect($scope.youDidIt).toBe(true);
});

然而,正如我所说的,我觉得这对ngModel的职责来说太过深入了,打破了你用自然可组合的指令得到的黑盒。

示例:http://plnkr.co/edit/BaWpxLuMh3HvivPUbrsd?p=preview

更新

在查看了AngularJS源代码后,我发现以下代码也适用:

代码语言:javascript
复制
it('trigger doIt', function() {
  el.find('input').trigger('input');
  expect($scope.youDidIt).toBe(true);
});

在某些浏览器中,这一事件看起来是不同的;input似乎适用于Chrome。

示例:http://plnkr.co/edit/rbZ5OnBtKMzdpmPkmn2B?p=preview

下面是relevant AngularJS code,它使用$sniffer服务来确定要触发的事件:

代码语言:javascript
复制
changeInputValueTo = function(value) {
  inputElm.val(value);
  browserTrigger(inputElm, $sniffer.hasEvent('input') ? 'input' : 'change');
};

即使这样,我也不确定我是否会以这种方式测试一个指令。

票数 31
EN

Stack Overflow用户

发布于 2016-09-06 05:54:54

我在谷歌上搜索了"angular directive trigger ng-change“,这个StackOverflow问题是我最接近有用的问题,所以我会回答”如何在指令中触发ng-change“,因为其他人肯定会出现在这个页面上,而我不知道如何提供这些信息。

在指令的link函数中,这将在您的元素上触发ng-change函数:

代码语言:javascript
复制
element.controller('ngModel').$viewChangeListeners[0]();

element.trigger("change")element.trigger("input")对我不起作用,我在网上能找到的其他东西也不起作用。

例如,在模糊上触发ng-change:

代码语言:javascript
复制
wpModule.directive('triggerChangeOnBlur', function () {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            element.on('blur', function () {
                element.controller('ngModel').$viewChangeListeners[0]();
            });
        }
    };
}]);

很抱歉,这没有直接回答OP的问题。我将非常乐意接受一些关于在哪里以及如何分享这些信息的合理建议。

票数 1
EN

Stack Overflow用户

发布于 2017-05-19 17:05:37

很简单,它可以在你的单元测试环境中工作:

代码语言:javascript
复制
spyOn(self, 'updateTransactionPrice');


var el = compile('<form name="form" latest novalidate json-schema="main.schema_discount" json-schema-model="main._data"><input type="text" ng-model="main._data.reverse_discount" ng-class="{ \'form-invalid\': form.reverse_discount.$invalid }" ng-change="main.transactionPrice(form);" name="reverse_discount" class="form-control-basic" placeholder="" ng-disabled="!main.selectedProduct.total_price"></form>')(scope);
el.find('input').triggerHandler('change');

expect(self.updateTransactionPrice).toHaveBeenCalled();
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17626604

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档